var integrity = `
This section describes mechanisms for ensuring the authenticity and integrity of OpenBadgeCredentials. At least one proof mechanism, and the details necessary to evaluate that proof, MUST be expressed for a [=credential=] to be a [=verifiable credential=]; that is, to be [=verifiable=].
The proof formats included in this specification fall into two categories:
- JSON Web Token Proof - Somtimes called VC-JWT, this format has a single implementation: the credential is encoded into a [=JWT=] which is then signed and encoded as a [=JWS=]. The JSON Web Token proof is called an external proof because the proof wraps the [=credential=] object.
- Linked Data Proofs - The credential is signed and the signature is used to form a Proof object which is appended to the credential. This format supports many different proof types. These are called embedded proofs because the proof is embedded in the data.
A third category of proof format called Non-Signature Proof is not covered by this specification. This category includes proofs such as proof of work.
This proof format relies on the well established JWT (JSON Web Token) [[RFC7519]] and JWS (JSON Web Signature) [[RFC7515]] specifications. A JSON Web Token Proof is a JWT signed and encoded as a [=Compact JWS=] string. The proof format is described in detail in [[VC-JOSE-COSE]], refered from Section 5.13 "Securing Mechanism Specifications" of [[[VC-DATA-MODEL-2.0]]]. That description allows several options which may inhibit interoperability. This specification limits the options while maintaining compatibility with [[VC-DATA-MODEL-2.0]] to help ensure interoperability.
Some of the terms used in this section include:
- JWT - "JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted." [[RFC7519]]
- JWS - "JSON Web Signature (JWS) represents content secured with digital signatures or Message Authentication Codes (MACs) using JSON-based data structures. Cryptographic algorithms and identifiers for use with this specification are described in the separate JSON Web Algorithms (JWA) specification and an IANA registry defined by that specification." [[RFC7515]]
- JWK - "A JSON Web Key (JWK) is a JavaScript Object Notation (JSON) data structure that represents a cryptographic key." [[RFC7517]]
- Compact JWS - "A compact representation of a JWS." [[RFC7515]]
A [=JWS=] is a signed [=JWT=] with three parts separated by period (".") characters. Each part contains a base64url-encoded value.
- JOSE Header - Describes the cryptographic operations applied to the JWT and optionally, additional properties of the JWT. [[RFC7515]]
- JWT Payload - The JSON object that will be signed. In this specification, the JWT Payload includes the OpenBadgeCredential.
- JWS Signature - The computed signature of the JWT Payload.
The JOSE Header, JWT Payload, and JWS Signature are combined to form a Compact JWS. To transform a [=credential=] into a [=Compact JWS=] takes 4 steps:
- Create the [=JOSE Header=], specifying the signing algorithm to use
- Create the [=JWT Payload=] from the [=credential=] to be signed
- Compute the signature of the [=JWT Payload=]
- Encode the resulting [=JWS=] as a [=Compact JWS=]
The resulting [=JWS=] proves that the [=issuer=] signed the [=JWT Payload=] turning the [=credential=] into a [=verifiable credential=].
When using the JSON Web Token Proof Format, the `proof` property MAY be ommitted from the OpenBadgeCredential. If a Linked Data Proof is also provided, it MUST be created before the JSON Web Token Proof Format is created.
The [=JOSE Header=] is a JSON object with the following properties (also called JOSE Headers). Additional JOSE Headers are NOT allowed.
| Property / JOSE Header | Type | Description | Required? |
|---|---|---|---|
| `alg` | String | The signing algorithm MUST be "RS256" as a minimum as defined in [[RFC7518]]. Support for other algorithms is permitted but their use limits interoperability. Later versions of this specification MAY add OPTIONAL support for other algorithms. See Section 6.1 RSA Key of the [[[SEC-11]]]. | Required |
| `kid` | URI | A URI that can be dereferenced to an object of type JWK representing the public key used to verify the signature. If you do not include a `kid` property in the header, you MUST include the public key in the `jwk` property. Be careful not to accidentally expose the JWK representation of a private key. See RFC7517 for examples of private key representations. The `JWK` MUST never contain `"d"`. |
Optional |
| `jwk` | JWK | A JWK representing the public key used to verify the signature. If you do not include a `jwk` property in the header, you MUST include the `kid` property. Be careful not to accidentally expose the JWK representation of a private key. See RFC7517 for examples of private key representations. The `JWK` MUST never contain `"d"`. |
Optional |
| `typ` | String | If present, MUST be set to `vc+ld+json+jwt`. | Optional |
| `cty` | String | If present, MUST be set to `vc+ld+json`. | Optional |
{
"alg": "RS256",
"kid": "https://example.edu/keys#key-1",
"typ": "JWT"
}
If you are going to use both external and embedded proof formats, add the embedded proofs prior to creating the JWT Payload.
The JWT Payload is the JSON object of the OpenBadgeCredential with the following properties (JWT Claims). Additional standard JWT Claims Names are allowed, but their relationship to the credential is not defined.
| Property / Claim Name | Type | Description | Required? |
|---|---|---|---|
| `exp` | NumericDate | The expiration time of the signature. | Optional |
| `iss` | URI | The `issuer.id` property of the OpenBadgeCredential. | Required |
| `jti` | URI | The `id` property of the OpenBadgeCredential. | Required |
| `nbf` | NumericDate | The `validFrom` property of the OpenBadgeCredential. | Required |
| `sub` | URI | The `credentialSubject.id` property of the OpenBadgeCredential. | Required |
1EdTech strongly recommends using an existing, stable library for this step.
This section uses the follow notations:
- `JOSE Header` - denotes the JSON string representation of the JOSE Header.
- `JWT Payload` - denotes the JSON string representation of the JWT Payload.
- `BASE64URL(OCTETS)` - denotes the base64url encoding of OCTETS per [[RFC7515]].
- `UTF8(STRING)` - denotes the octets of the UTF-8 [[RFC3629]] representation of STRING, where STRING is a sequence of Unicode [[UNICODE]] characters.
- The concatenation of two values A and B is denoted as `A || B`.
The steps to sign and encode the credential as a Compact JWS are shown below:
- Encode the JOSE Header as \`BASE64URL(UTF8(JOSE Header))\`.
- Encode the JWT Payload as \`BASE64URL(JWT Payload)\`.
- Concatenate the encoded JOSE Header and the encoded JSW Payload as \`A | "." | B\`.
- Calculate the \`JWS Signature\` for \`C\` as described in [[RFC7515]].
- Encode the signature as \`BASE64URL(JWS Signature)\`.
- Concatenate \`C\` and \`E\` as \`C | "." | E\`.
The resulting string is the Compact JWS representation of the credential. The Compact JWS includes the credential AND acts as the proof for the credential.
Verifiers that receive a OpenBadgeCredential in Compact JWS format MUST perform the following steps to verify the embedded credential.
-
Base64url-decode the JOSE Header.
-
If the header includes a `kid` property, Dereference the `kid` value to retrieve the public key JWK.
-
If the header includes a `jwk` property, convert the `jwk` value into the public key JWK.
-
Use the public key JWK to verify the signature as described in "Section 5.2 Message Signature or MAC Validation" of [[RFC7515]]. If the signature is not valid, the credential proof is not valid.
1EdTech strongly recommends using an existing, stable library for this step.
-
Base64url-decode the JWT Payload segment of the Compact JWS and parse it into a JSON object.
-
Convert the value of the JWT Payload to an OpenBadgeCredential and continue with [[[#jwt-verify-credential]]].
Credentials created following [[[VC-DATA-MODEL]]] ([[VC-DATA-MODEL]]) store the OpenBadgeCredential in the \`vc\` claim of the JWT Payload. In this case, the contents of the \`vc\` claim must be converted to an OpenBadgeCredential and continue with [[[#jwt-verify-credential]]].
- The JSON object MUST have the `iss` claim, and the value MUST match the `issuer.id` of the OpenBadgeCredential object. If they do not match, the credential is not valid.
- The JSON object MUST have the `sub` claim, and the value MUST match the `credentialSubject.id` of the OpenBadgeCredential object. If they do not match, the credential is not valid.
- The JSON object MUST have the `nbf` claim, and the NumericDate value MUST be converted to a DateTime, and MUST equal the `validFrom` of the OpenBadgeCredential object. If they do not match or if the `validFrom` has not yet occurred, the credential is not valid.
- The JSON object MUST have the `jti` claim, and the value MUST match the `id` of the OpenBadgeCredential object. If they do not match, the credential is not valid.
- If the JSON object has the `exp` claim, the NumericDate MUST be converted to a DateTime. If the resulting DateTime is before the current time, the signature has expired and the verification MUST be made using linked data proofs of the credential. If the credential doesn't have linked data proofs, the credential is not valid.
This standard supports the Linked Data Proof format. In order to opt for this format you MUST use the [[[VC-DI-EDDSA]]] suite.
Perform these steps to attach a Linked Data Proof to the credential:
- Create an instance of Multikey as shown in Section 2.1.1 DataIntegrityProof of [[VC-DI-EDDSA]].
- Using the key material, sign the credential object as shown in Section 7.1 Proof Algothim of [[DATA-INTEGRITY-SPEC]] to produce a Proof as shown in Section 2.2.1 DataIntegrityProof of [[VC-DI-EDDSA]] with a `proofPurpose` of "assertionMethod".
- Add the resulting proof object to the credential `proof` property.
Verify the Linked Data Proof signature as shown in Section 7.2 Proof Verification Algorthim of [[DATA-INTEGRITY-SPEC]].
[=Issuers=] will need to manage asymmetric keys. The mechanisms by which keys are minted and distributed is outside the scope of this specification. See Section 6. Key Management of the [[[SEC-11]]].
All the proof formats in this specification, and all Digital Integrity proofs in general, require the [=verifier=] to "dereference" the public key from a URI. Dereferencing means using the URI to get the public key in JWK format. This specification allows the use of an HTTP URL (e.g. `https://1edtech.org/keys/1\`) or a DID URL (e.g. `did:key:123`), but only requires HTTP URL support.
`;