Skip to main content

Digitally Validate a Degree

In this tutorial, you will use the WASM binding of the IOTA Identity framework to digitally prove the existence and validity of a degree.

To follow along, please clone the tutorials repository and install the npm/yarn package @iota/identity-wasm@dev, as described in the WASM binding documentation.

Problem Description

Alice recently graduated from the University of Oslo with a Bachelor of Computer Science. Now, she wants to apply for a remote job at the IOTA Foundation and needs to digitally prove the existence and validity of her degree. What she needs is an immutable and verifiable credential, approved by both the University of Oslo and herself, before presenting it to her potential employer.

Roles

As described in the Digital Identities Solution, IOTA Identity builds on the W3C's proposed standards for a digital identity framework based on three roles:

  • Holder: Alice
  • Issuer: University of Oslo
  • Verifier: IOTA Foundation

Terms

TermDefinition
Decentralized Identifier (DID)A globally unique persistent identifier that does not require a centralized registration authority and is often generated and/or registered cryptographically.
DID SubjectThe entity identified by a DID and described by a DID document. Anything can be a DID subject: person, group, organization, physical thing, digital thing, logical thing, etc.
DID DocumentA set of data describing the DID subject, including mechanisms, such as cryptographic public keys, that the DID subject or a DID delegate can use to authenticate itself and prove its association with the DID
Verification MethodA set of parameters that can be used together with a process to independently verify a proof. For example, a cryptographic public key can be used as a verification method for a digital signature; in such usage, it verifies that the signer possessed the associated cryptographic private key.
Verifiable CredentialA standard data model and representation format for cryptographically-verifiable digital credentials. It is signed by the issuer, to prove control over the Verifiable Credential with a nonce or timestamp.
Verifiable PresentationA Verifiable Presentation is the format in which a (collection of) Verifiable Credential(s) gets shared. It is signed by the subject, to prove control over the Verifiable Credential with a nonce or timestamp.
DID ResolutionThe process that takes as its input a DID and a set of resolution options and returns a DID document in a conforming representation plus additional metadata.
Merkle Key CollectionBy using a Merkle Tree you can verify the ownership of multiple private keys (Must be a power of 2) with only one public key.

Flow-Chart

banner

Key Storage

  • In this tutorial, you will store the key pairs for every newly created or updated DID document in Weakhold.
  • Ok, ok, it’s just a couple of JSON files in a folder, but it gets the job done.
  • The files are stored in the Weakhold Folder (e.g. ./weakhold/Alice.json).
This is no proper key storage solution.

For professional IOTA implementations we strongly recommend using our key management framework Stronghold.

Example Weakhold file:

{
"subject": "Alice",
"did": "did:iota:Bakoe4HD4uwekMuyMkeo7mCsA2frXej68M4QyFvEpo2G",
"messageId": "7c25309fe97f2cf2d609cf83f31e8838795dd16d235c7a56566970309a0d6dbd",
"explorerUrl": "https://explorer.iota.org/mainnet/message/7c25309fe97f2cf2d609cf83f31e8838795dd16d235c7a56566970309a0d6dbd",
"authKey": {
"type": "ed25519",
"public": "ExwZKmF9y2N4mKnEaeUU7bFyCkZ5oVjjK3ojooJKNxUK",
"secret": "G83815cmpPadAzs52GmpwS614xpaAWWQxUexmRVNkg75"
},
"verifKey": {
"type": "ed25519",
"public": "F9aM5Q9gGXb6Dswe8eSdsz5eDQX2ErTnpGDjFj5LMVvx",
"secret": "12S3U2u8ofyju53tmGsG9PKQfkBM8rhzL9BUBhfGqpdm"
}
}

Steps

In this process, you will complete the different steps from the perspective of one of the mentioned roles above:

1. Holder: Create a DID.

The first thing you will need to do in this tutorial is to create a DID(Decentralized Identifier) Document for Alice.

After this step, you will find Alice's weakhold file in ./weakhold/Alice.json.

 createDid('Alice');

2. Issuer: Create a DID

Once you have created the Alice's DID(Decentralized Identifier), you should do the same for the University of Oslo.

After this step, you will find the University of Oslo's weakhold file in ./weakhold/UniversityofOslo.json.

 createDid('University of Oslo');

3. Issuer: Add a Verification Method

Since the university will need to verify Alice's degree, you should add a "degreeVerifications" verification method to the University's DID document.

The University will have to sign more than just Alice's degree, so you should generate this verification method with a set of Merkle keys. These signatures can all be proved by a single public key, while retaining the ability to revoke them separately.

Note that the newly added verification method is of the type MerkleKeyCollection.

 //Add verification method with collection of merkle keys to issuer DID
//This enables the issuer to sign and revoke multiple documents without having to remove the verification method for each revocation
let issuer = getWeakholdObject('./weakhold/UniversityofOslo.json')
let issuerVerificationMethod = "degreeVerifications";

addVerificationMethod(
subjectName = issuer.subject,
did = issuer.did,
authKey = KeyPair.fromJSON(issuer.authKey),
verificationMethodName = issuerVerificationMethod,
merkleKeys = true);

4. Holder: Add a Verification Method

Alice will need a verification method to present her degree to a third party, so you should add a verification method to her DID document.

Since Alice only needs one key pair to her credential's verifiable presentation, she will generate this verification method with a simple private/public key pair.

Note that the newly added verification method is of the type "Ed25519VerificationKey".

 //Add verification method to holder DID
let holder = getWeakholdObject('./weakhold/Alice.json')
let holderVerificationMethod = "aliceDegreePresentation";

addVerificationMethod(
subjectName = holder.subject,
did = holder.did,
authKey = KeyPair.fromJSON(holder.authKey),
verificationMethodName = holderVerificationMethod,
merkleKeys = false);

###5. Holder: Set Up a Document

You should set up a document representing Alice's degree, containing her DID which will later be signed by the issuer.

 //This part is already hard coded in "createVerifiableCredential.js"
//Create credential indicating the degree earned by Alice
const credentialSubject = {
"id": holderDid,
"name": holderSubject,
"degreeName": "Bachelor of Computer Science",
"degreeType": "BachelorDegree",
"GPA": "4.0"
}

6. Issuer: Sign the Document

To verify the degree document created in step 5, you should sign the degree document with the first key in the Merkle key collection of the University's verification method.

This step will generate a verifiable credential. After this step you will find the verifiable credential for Alice's degree in ./signedCredentials/offlineVerifiableCredential.json.

 //Issue and sign verifiable credential from weakhold object
let issuer = getWeakholdObject('./weakhold/UniversityofOslo.json')
let issuerVerificationMethod = "degreeVerifications";
let holder = getWeakholdObject('./weakhold/Alice.json')

createVerifiableCredential(
issuer.subject,
issuer.did,
KeyCollection.fromJSON(issuer.verifKey),
issuerVerificationMethod,
holder.did,
holder.subject);

7. Holder: Verify the Credentials

Since Alice wants to be sure that her credentials are properly verified, you should verify the credentials to make sure it was actually signed by a key associated to the University DID.

 let signedVcPath = './signedCredentials/offlineVerifiableCredential.json';
checkVerifiableCredential(signedVcPath);

8. Holder: Sign a Verifiable Credential

Alice need a verifiable presentation to send to the IOTA Foundation, so you should sign the verifiable credential with a private key of Alice's verification method.

This step will generate a verifiable presentation. After this step you will find the verifiable presentation of Alice's degree in ./signedCredentials/offlineVerifiablePresentation.json.

 //Issue and sign verifiable credential from weakhold object
let holder = getWeakholdObject('./weakhold/Alice.json')
let holderVerificationMethod = "aliceDegreePresentation";
let signedVcPath = './signedCredentials/aliceVerifiableCredential.json';

createVerifiablePresentation(
holder.subject,
holder.did,
KeyPair.fromJSON(holder.verifKey),
holderVerificationMethod,
signedVcPath);

9. Verifier: Verify Alice's and the University's Signatures

The IOTA Foundation need to verify the presentation's signatures, so you should use Alice's and the University's public keys to verify their verifiable presentation.

 let signedVpPath = './signedCredentials/offlineVerifiablePresentation.json';
checkVerifiablePresentation(signedVpPath);

10. Issuer: Revoke the Verification for Alice's Credential.

Unfortunately the University found out, that Alice had cheated on her final exam. Therefore, the University wants to revoke the verification of Alice's credential.

Since they used a Merkle key collection as a verification method, you can do this two ways:

1. Remove the whole verification method

//Remove whole verification method and thus also the used key pair for signatures
let issuer = getWeakholdObject('./weakhold/UniversityofOslo.json');
let verificationMethodName = "degreeVerifications";

removeVerificationMethod(
issuer.subject,
issuer.did,
KeyPair.fromJSON(issuer.authKey),
verificationMethodName );

2. Only revoke the one Merkle key used for the signature.

//Revoke signatures, which used the first key in the Merkle key collection
let issuer = getWeakholdObject('./weakhold/UniversityofOslo.json');
let verificationMethodName = "degreeVerifications";

removeMerkleKey(
issuer.subject,
issuer.did,
KeyPair.fromJSON(issuer.authKey),
verificationMethodName,
KeyCollection.fromJSON(issuer.verifKey));

Note that you could also revoke Alice's signature on the verifiable presentation, by removing her verification method.

11. Verifier: Verify Signatures Again

The IOTA Foundation verifies Alice's and the University's signatures again by checking the verifiable presentation and finds out that the University revoked their signature.

let signedVpPath = './signedCredentials/signedVP.json';
checkVerifiablePresentation(signedVpPath);