@gaia-x/json-web-signature-2020
TypeScript icon, indicating that this package has built-in type declarations

2.0.1 • Public • Published

Gaia-X JSON Web Signature 2020

Coverage NPM Version NPM Downloads NPM bundle size GitLab License

🪶 A lightweight JsonWebSignature2020 signing and verification Typescript library by Gaia-X AISBL

Requirements

This library is designed to be compatible with Node version 18+.

The main requirements to run this library are to have a Typescript enabled project and an execution environment connected to the Internet to be able to resolve DIDs.

Getting Started

All you need to do is install this package.

npm install @gaia-x/json-web-signature-2020

You can then check out our examples below to get started signing and verifying verifiable credentials.

Currently Supported

DID Types

This library is mainly orientated towards Gaia-X verifiable credentials which are only based on did:web at the moment so other DID types are not supported.

DID Type Supported
did:web
did:key
did:ethr
did:jwk
did:btcr
did:dns
did:ebsi
...

ℹ️ Please note that other DID resolvers can easily be integrated in this project as it is based on did-resolver which offers a plug-and-play driver approach.

Key Algorithms

This library supports all the algorithms supported by jose as it is used to import public & private keys. Please refer to jose's implemented specifications chapter to have more details.

Algorithm Supported
HS256
HS384
HS512
PS256
PS384
PS512
RS256
RS384
RS512
ES256
ES256K
ES384
ES512
EdDSA

Public Key Formats

Public keys are used for verifying verifiable credential proofs and are resolved via the verification method DID, the following public key formats are supported when collected from a DID document.

Format Supported
JWK
Multibase

Create a Verifiable Credential

A verifiable credential is created by signing a document with a private key, this process creates a proof attribute for the verifiable credential with a jws attribute containing the signature. This avoids tampering with the verifiable credential after it has been signed.

JSON Web Signature 2020

To sign a document (hence making it a verifiable credential) with the JSON Web Signature 2020 specification, the JsonWebSignature2020Signer can be used in the following manner.

const document: Omit<VerifiableCredential, 'proof'> = { ... }
const signer: Signer = new JsonWebSignature2020Signer({
  privateKey: await jose.importPKCS8(privateKeyPem, privateKeyAlgorithm),
  privateKeyAlgorithm: 'ES256',
  verificationMethod: 'did:web:my-domain.com#key-1'
})

const verifiableCredential: VerifiableCredential = await signer.sign(document)

👇 Please see the below Verification Methode chapter for more details about the verificationMethod argument.

Gaia-X JSON Web Signature 2020

The same method can be used with the GaiaXSignatureSigner

const document: Omit<VerifiableCredential, 'proof'> = { ... }
const signer: Signer = new GaiaXSignatureSigner({
  privateKey: await jose.importPKCS8(privateKeyPem, privateKeyAlgorithm),
  privateKeyAlgorithm: 'ES256',
  verificationMethod: 'did:web:my-domain.com#key-1'
})

const verifiableCredential: VerifiableCredential = await signer.sign(document)

👇 Please see the below Verification Methode chapter for more details about the verificationMethod argument.

Verification Method

The verificationMethod argument in the above examples corresponds to the verifiable credential's proof.verificationMethod attribute. This attribute is built by concatenating the DID and the public key ID with a # separating them.

Verify a Verifiable Credential

Verifiers

All verifiable credential verification is done through what we call a Verifier, it is in charge of coordinating all the steps and components necessary to that verification.

Verifier Sequence Diagram
sequenceDiagram
    participant S as Software
    participant V as Verifier
    participant R as DID Resolver
    participant H as Hasher

S->>+V: Call verify() with Verifiable Credential
break when Verifiable Credential is malformed
    V-->>S: Raise an Exception
end
V->>V: Separate Proof & Document
V->>V: Extract DID
V->>+R: Send DID
break when DID is not resolvable
    R-->>S: Raise an Exception
end
R->>R: Resolve DID to Collect DID Document
R->>-V: Return DID Document
V->>V: Extract Public Key from DID Document
V->>+H: Send Document & Proof
H->>H: Canonize/Normalize JSON-LD
break when normalization fails
    H-->>S: Raise an Exception
end
H->>H: SHA-256 Hashed Normalized Data
H->>-V: Return a Hash
V->>V: Verify the Proof's JWS
break when the proof verification fails
    V-->>S: Raise an Exception
end
V->>-S: Void

👀 Don't hesitate to check out the *.spec.ts test files to find some real life examples of the usage of verifiers.

JSON Web Signature 2020

To verify a JSON Web Signature 2020 signed verifiable credential, you will need to instantiate the JsonWebSignature2020Verifier class which packs all the necessary logic to validate it using the proof attribute.

const verifier: Verifier = new JsonWebSignature2020Verifier()

try {
  await verifier.verify(verifiableCredential)
} catch (e) {
  // Manage the verification exception
}

Gaia-X JSON Web Signature 2020

Just like the previous chapter, Gaia-x JSON Web Signature 2020 can be verified with the GaiaXSignatureVerifier class.

const verifier: Verifier = new GaiaXSignatureVerifier()

try {
  await verifier.verify(verifiableCredential)
} catch (e) {
  // Manage the verification exception
}

Overriding with Options

Developers using this library will have different goals and needs depending on their application. To fit those needs, options have been introduced to be able to tweak the library's behaviour.

Using Options

Each component of this library can be tweaked with its own Options object :

  • Hasher uses the base Options class
  • Signer uses the SignerOptions class which extends Options
  • Verifier uses the VerifierOptions class which extends Options
// Hasher
const hasherOptions: Options = {
  documentLoader: myDocumentLoader,
  safe: false
}
const hasher: Hasher = new JsonWebSignature2020Hasher(hasherOptions)

// Signer
const signerOptions: Options = {
  privateKey: myPrivateKey,
  privateKeyAlg: myPrivateKeyAlg,
  verificationMethod: myVerificationMethod,
  documentLoader: myDocumentLoader,
  safe: false
}
const signer: Signer = new JsonWebSignature2020Signer(signerOptions)

// Verifier
const verifierOptions: Options = {
  didResolver: myDidResolver,
  documentLoader: myDocumentLoader,
  safe: false
}
const verifier: Verifier = new JsonWebSignature2020Verifier(verifierOptions)

☝️ Don't hesitate to check out the option classes in the src/options/ folder to find out which attributes are available. Modern IDEs integrate attribute resolution and autocompletion which can help you navigate possibilities.

Custom DidResolver

If a developer needs to use other DID methods or a custom DID resolver, this can be done through the Verifier's constructor.

const didResolver: CustomDidResolver = new CustomDidResolver()
const verifier: Verifier = new JsonWebSignature2020Verifier({ didResolver })

Offline Contexts

In certain cases, like verifying many verifiable credentials per second, rate-limiting can cause issues with JSON-LD context resolving. An OfflineDocumentLoaderBuilder has been provided in this library to locally resolve given contexts, it can easily be used by injecting it in the wanted Hasher or Verifier.

Custom contexts can be added to this document loader by calling the OfflineDocumentLoaderBuilder#addContext(string, any) method with the context's URL and its content which can be imported from a JSON file.

For Verifiers

const offlineDocumentLoader: DocumentLoader = new OfflineDocumentLoaderBuilder().build()
const verifier: Verifier = new JsonWebSignature2020Verifier({ documentLoader: offlineDocumentLoader })

For Hashers

const offlineDocumentLoader: DocumentLoader = new OfflineDocumentLoaderBuilder().build()
const hasher: Verifier = new JsonWebSignature2020Hasher({ documentLoader: offlineDocumentLoader })

With Custom Contexts

import MyContext from 'contexts/my-context.json'
import CustomContext from 'contexts/custom-context.json'

const offlineDocumentLoader: DocumentLoader = new OfflineDocumentLoaderBuilder()
    .addContext('https://my-context.org/2024/entities/v1', MyContext)
    .addContext('https://custom-context.org/2024/entities/v1', CustomContext)
    .build()

🔍 Make sure you have "resolveJsonModule": true is your tsconfig.json configuration file in order to be able to import the contexts from JSON files.

Package Sidebar

Install

npm i @gaia-x/json-web-signature-2020

Weekly Downloads

56

Version

2.0.1

License

EPL-2.0

Unpacked Size

168 kB

Total Files

109

Last publish

Collaborators

  • vincentkelleher
  • arthursore
  • ysellamigx
  • adeprez
  • egavard-gaia-x