Skip to content

openwallet-foundation-labs/sd-jwt-vc-dm

Repository files navigation

SD JWT VCDM Typescript

Typescript implementation of SD JWT VCDM profile.

A library that integrates SD-JWT with W3C Verifiable Credentials Data Model and implements JAdES digital signature standards.

Features

SD-JWT VCDM Data Model Profile

This library provides interoperability between SD-JWT (Selective Disclosure JWT) and W3C Verifiable Credentials Data Model:

  • Issue Verifiable Digital Credentials in SD-JWT VC format while maintaining W3C VCDM compliance
  • Support for Selective Disclosure capabilities
  • Seamless integration with standard VC verification processes

JAdES Digital Signature Integration

Implements JAdES (JSON Advanced Electronic Signatures) standard for SD-JWT:

  • B-B (Basic - Baseline): Full support for basic signature format
  • B-T (Basic with Time): Basic support for signatures with timestamp
  • B-LT (Basic Long-Term): Structure defined
  • B-LTA (Basic Long-Term with Archive timestamps): Structure defined

Installation

pnpm add sd-jwt-vcdm

Usage

B-B

import { JAdES, parseCerts, createKidFromCert } from 'sd-jwt-jades';
import * as fs from 'fs';
import { createPrivateKey } from 'node:crypto';

(async () => {
  const jades = new JAdES.Sign({ data: 'data 1', target: 'data 2' });

  const certPem = fs.readFileSync('./fixtures/certificate.crt', 'utf-8');
  const certs = parseCerts(certPem);
  const kid = createKidFromCert(certs[0]);

  const keyPem = fs.readFileSync('./fixtures/private.pem', 'utf-8');
  const privateKey = createPrivateKey(keyPem);

  await jades
    .setProtectedHeader({
      alg: 'RS256',
      typ: 'jades',
    })
    .setX5c(certs)
    .setDisclosureFrame({
      _sd: ['data'],
    })
    .setSignedAt()
    .sign(privateKey, kid);

  const serialized = jades.toJSON();
  console.log(serialized);
})();

B-T

import { JAdES, parseCerts, createKidFromCert } from 'sd-jwt-jades';
import * as fs from 'fs';
import { createPrivateKey } from 'node:crypto';

(async () => {
  const jades = new JAdES.Sign({ data: 'data 1', target: 'data 2' });

  const certPem = fs.readFileSync('./fixtures/certificate.crt', 'utf-8');
  const certs = parseCerts(certPem);
  const kid = createKidFromCert(certs[0]);

  const keyPem = fs.readFileSync('./fixtures/private.pem', 'utf-8');
  const privateKey = createPrivateKey(keyPem);

  await jades
    .setProtectedHeader({
      alg: 'RS256',
      typ: 'jades',
    })
    .setX5c(certs)
    .setDisclosureFrame({
      _sd: ['data'],
    })
    .setSignedAt()
    .setUnprotectedHeader({
      etsiU: [
        {
          sigTst: {
            tstTokens: [
              {
                val: 'Base64-encoded RFC 3161 Timestamp Token',
              },
            ],
          },
        },
      ],
    })
    .sign(privateKey, kid);

  const serialized = jades.toJSON();
  console.log(serialized);
})();

B-LT

import { JAdES, parseCerts, createKidFromCert } from 'sd-jwt-jades';
import * as fs from 'fs';
import { createPrivateKey } from 'node:crypto';

(async () => {
  const jades = new JAdES.Sign({ data: 'data 1', target: 'data 2' });

  const certPem = fs.readFileSync('./fixtures/certificate.crt', 'utf-8');
  const certs = parseCerts(certPem);
  const kid = createKidFromCert(certs[0]);

  const keyPem = fs.readFileSync('./fixtures/private.pem', 'utf-8');
  const privateKey = createPrivateKey(keyPem);

  await jades
    .setProtectedHeader({
      alg: 'RS256',
      typ: 'jades',
    })
    .setX5c(certs)
    .setDisclosureFrame({
      _sd: ['data'],
    })
    .setSignedAt()
    .setUnprotectedHeader({
      etsiU: [
        {
          sigTst: {
            tstTokens: [
              {
                val: 'Base64-encoded RFC 3161 Timestamp Token',
              },
            ],
          },
        },
        {
          xVals: [
            { x509Cert: 'Base64-encoded Trust Anchor' },
            { x509Cert: 'Base64-encoded CA Certificate' },
          ],
        },
        {
          rVals: {
            crlVals: ['Base64-encoded CRL'],
            ocspVals: ['Base64-encoded OCSP Response'],
          },
        },
      ],
    })
    .sign(privateKey, kid);

  const serialized = jades.toJSON();
  console.log(serialized);
})();

B-LTA

import { JAdES, parseCerts, createKidFromCert } from 'sd-jwt-jades';
import * as fs from 'fs';
import { createPrivateKey } from 'node:crypto';

(async () => {
  const jades = new JAdES.Sign({ data: 'data 1', target: 'data 2' });

  const certPem = fs.readFileSync('./fixtures/certificate.crt', 'utf-8');
  const certs = parseCerts(certPem);
  const kid = createKidFromCert(certs[0]);

  const keyPem = fs.readFileSync('./fixtures/private.pem', 'utf-8');
  const privateKey = createPrivateKey(keyPem);

  await jades
    .setProtectedHeader({
      alg: 'RS256',
      typ: 'jades',
    })
    .setX5c(certs)
    .setDisclosureFrame({
      _sd: ['data'],
    })
    .setSignedAt()
    .sign(privateKey, kid);

  const serialized = jades.toJSON();
  console.log(serialized);
})();

License

Apache License 2.0

References

About

Typescript implementation of SD JWT VCDM

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Contributors 4

  •  
  •  
  •  
  •