# repchain-vc-java-sdk **Repository Path**: BTAJL/repchain-vc-java-sdk ## Basic Information - **Project Name**: repchain-vc-java-sdk - **Description**: 基于RepChain区块链的可验证凭据(Verifiable Credential, VC)SDK(Java语言版) - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-06-10 - **Last Updated**: 2024-08-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## repchain-vc-java-sdk repchain-vc-java-sdk,基于RepChain区块链的可验证凭据(Verifiable Credential, VC)SDK(Java语言版)。 ### 背景介绍 我们日常生活中需要使用到各种各样的凭据/证件,比如对于个人而言,会使用到身份证、学位证、护照以及疫苗接种凭证等;对于组织机构而言,需要营业执照等;对于物品而言,可能需要产品合格证及藏品鉴定证等。 可验证凭据(VerifiableCredential,VC)[1]为我们提供了一种以数字化方式来表示及使用凭据的方案,在方便凭据的保存、传输及验证的同时,还为使用者提供了保护其隐私信息的能力。 基于此,我们提出了基于RepChain区块链的可验证凭据应用方案,并在这里为大家提供相应的SDK,希望可以帮助开发者快速实现可验证凭据相关业务逻辑,以支撑其相应业务应用。 ### 使用 可验证凭据的一般使用流程如下图所示: ![可验证凭据生命周期](docs/my-verifiable-credentials-lifeCycle.drawio.svg) #### 注册可验证凭据属性结构 首先,需要根据具体的业务需求,定义好可验证凭据属性结构(Credential Claims Scheme, CCS),并由特定机构作为凭据属性结构创建者向RepChain区块链注册可验证凭据属性结构CCS。比如在某场景中,需由教育主管部门来定义和创建学位证书的属性结构,或是由质量监督管理部门定义和创建商品合格证的属性结构。基于该属性结构的可验证凭据都应该使用该属性结构来填充属性,并指明其可验证凭据遵循的属性结构。 示例代码如下: ```Java import com.rep.vc.utils.Config; import com.rep.vc.models.ccs.CredentialClaimStruct; import com.rep.vc.models.ccs.CredentialClaimStructAttr; import com.rep.vc.roles.CCSCreator; // 配置欲连接的RepChain节点地址 Config.getInstance().setHostPeer("localhost:8081"); // ccs创建者did,账户成功注册后会生成,其格式为did:rep:<网络名>:<账户标识> String ccsCreatorDid = "did:rep:example:123456"; // ccs创建者本次操作使用的证书名称 String ccsCreatorCertName = "creator"; // ccs创建者本次操作使用的私钥(pem格式字符串) String ccsCreatorPrvKey = "-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGByq........\n-----END PRIVATE KEY-----"; CCSCreator creator = new CCSCreator(ccsCreatorDid, ccsCreatorCertName, ccsCreatorPrvKey); // 构建ccs对象 CredentialClaimStructAttr[] attrs = new CredentialClaimStructAttr[6]; attrs[0] = new CredentialClaimStructAttr("serialNumber", "String", true, "学位证书编号"); attrs[1] = new CredentialClaimStructAttr("id", "String", true, "学位证书获得者did标识"); attrs[2] = new CredentialClaimStructAttr("name", "String", true, "学位获得者姓名"); attrs[3] = new CredentialClaimStructAttr("degree", "String", true, "学位名称"); attrs[4] = new CredentialClaimStructAttr("date", "String", true, "学位授予日期"); attrs[5] = new CredentialClaimStructAttr("university", "String", true, "学位授予学校(单位)"); CredentialClaimStruct ccs = new CredentialClaimStruct( "CCS-001", "UniversityDegreeCredential", "1.0", "2021-04-10T12:20:39Z", "高等学校学位证书", attrs ); // 注册ccs到RepChain区块链 try { creator.signupCCS2RepChain(ccs); } catch (Exception e) { e.printStackTrace(); } ``` 上述示例代码,将在RepChain区块链中创建一种表示学位证书的可验证凭据属性结构。 #### 颁发可验证凭据 根据具体业务需求,由可验证凭据颁发机构收集特定的凭据属性信息,比如收集用户在前端填写的数据,颁发机构作为凭据颁发者填充可验证凭据属性值,并对其签名,以创建可验证凭据。 凭据颁发者签发了可验证凭据之后,还需要在RepChain区块链中注册相应的可验证凭据状态信息,以供后续凭据验证方进行验证。 示例代码如下: ```Java import com.rep.vc.utils.Config; import com.rep.vc.utils.SignatureTools; import com.rep.vc.roles.VCIssuer; import com.rep.vc.models.vc.VCMetadata; import com.rep.vc.models.vc.VCClaim; import com.rep.vc.models.vc.Credential; import com.rep.vc.models.vc.CredentialAtomic; import com.rep.vc.models.vc.VerifiableCredential; ...... import java.util.HashMap; import java.util.Map; // 凭据颁发者did String issuerDid = "did:rep:example:123" // 凭据颁发者本次操作所用证书名称 String issuerCertName = "issuer-1" // 凭据颁发者本次操作所用私钥(pem格式字符串,也可为PrivateKey对象) String issuerPrvKey = "-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGByq........\n-----END PRIVATE KEY-----"; VCIssuer issuer = new VCIssuer(issuerDid, issuerCertName, issuerPrvKey); // 凭据元数据 VCMetadata metadata = new VCMetadata(); metadata.setId("0x123456"); metadata.addType("UniversityDegreeCredential"); metadata.setClaimScheme("CCS-001"); metadata.setValidFrom("2021-03-26T10:08:59Z"); metadata.setValidUntil("2022-03-26T10:08:59Z"); // 凭据属性 Map credentialSubjectAtomic = new HashMap<>(); credentialSubjectAtomic.put("0", new VCClaim("serialNumber", "2021063012342176")); credentialSubjectAtomic.put("1", new VCClaim("id", "did:rep:example:987654")); credentialSubjectAtomic.put("2", new VCClaim("name", "Tom")); credentialSubjectAtomic.put("3", new VCClaim("degree", "Master")); credentialSubjectAtomic.put("4", new VCClaim("date", "2021-06-30")); credentialSubjectAtomic.put("5", new VCClaim("university", "RepChain Training University")); // 创建凭据对象 Credential credential = new CredentialAtomic(metadata, credentialSubjectAtomic); // 凭据颁发者签发可验证凭据 VerifiableCredential vc = issuer.issueVerifiableCredential( credential, SignatureTools.ECSecp256k1Sig ); // 将可验证凭据导出为Json字符串 String vcJson = vc.exportAsJsonStr(); /* * Json格式VC示例: * { * "@context": [ "https://www.w3.org/2018/credentials/v1" ], * "id": "0x123456", * "type": [ "VerifiableCredential", "UniversityDegreeCredential" ], * "claimScheme": "CCS-001", * "issuer": "did:rep:example:123", * "issued": "2021-03-26T10:08:09Z", * "validFrom": "2021-03-26T10:08:59Z", * "validUntil": "2022-03-26T10:08:59Z", * "credentialSubject": { * "0": { "serialNumber": "2021063012342176" }, * "1": { "id": "did:rep:example:987654" }, * "2": { "name": "Tom" }, * "3": { "degree": "Master" }, * "4": { "date": "2021-06-30" }, * "5": { "university": "RepChain Training University"} * }, * "proof":{ * "type": "EcdsaSecp256k1Signature", * "created": "2021-03-26T10:09:00.719Z", * "verificationMethod": "did:rep:example:123#issuer-1", * "signature": { * "0": "MEUCIQDheXVNMujuV42jFx/CrhNm0zJQguLJV6IDBg7ttxbq4AIgYGJeY73CYT55WSwXWdDnjXjXEBK/pnYNs8bq77MbRJM=", * "1": "MEQCIGZElCFmhcXB9T42lYQ+qNcBkJbhCHxvCZ3SkjXUelzDAiA9bt1KoMZT+NAT3bo70gLMTEba3r+2r0erAG8nchVUSQ==", * "2": "MEQCIF7GpDod/y57h0LPzwt7mVI+XbRspGh4nHv2WWlU+yLUAiAulP/D/0fojwmUofOnACfu2Bo6vz462Ire61rtuIJ4jg==", * "3": "MEUCIQCi/0aZdVcgFn/6La9zRAFgyM86Dup6aocVAIpXNBVSAAIgHM+arEn1lK0q52CNmuq/aHtJDnTDOukACQ54cVE9pco=", * "4": "MEUCIAglrY2LpemyEh62reRHgBtez/7roxi2+w9Y4NRWlfAnAiEAmOqq7+2w1dA2MxzSpsfs6ua0l3OWt7oCr7N+eab1/Zs=", * "5": "MEQCIGxyKXSRIQmiYmAe2gRldr/UXTi9+j2Onv2QuFeGw/bWAiBRadb5+JrX7IBhuHs+pKvw5dvNO1dI3Mlb1/spW3LExw==" * } * } * } */ // 向RepChain区块链注册及初始化可验证凭据状态(包括可验证凭据属性的有效性状态) try { issuer.signupVCStatus(metadata.getId(), "VALID"); } catch (Exception e) { e.printStackTrace(); } ``` 上述代码创建了一个表示数字学位证书的可验证凭据,可将其导出为Json字符串,方便在不同网络实体间进行传递使用,比如通过网络将其传递给相应的可验证凭据拥有者。 #### 序列化和反序列化可验证凭据 为方便可验证凭据在不同网络实体间的传递使用,可对其进行序列化为Json字符串或者二进制数据。 示例代码: ```Java // 序列化为Json字符串 String vcJson = vc.exportAsJsonStr(); // 序列化为二进制数据 byte[] vcBytes = vc.exportAsBytes(); ``` 当实体接收到Json字符串格式或二进制格式的可验证凭据时,可以对其进行反解析,以得到相应的可验证凭据对象,方便后续选择性披露属性以及验证有效性等操作。 示例代码: ```Java import com.rep.vc.models.vc.VerifiableCredential; // 反序列化Json字符串格式数据 VerifiableCredential vcFromJson = VerifiableCredential.parseFrom(vcJson); // 反序列化二进制格式数据 VerifiableCredential vcFromBytes = VerifiableCredential.parseFrom(vcBytes); ``` #### 使用可验证凭据 在一般场景下,当用户访问某种业务应用时,应用服务方可能会需要用户提供其持有的相应可验证凭据信息,并对其进行验证。作为凭据持有者,用户需构建包含了相应可验证凭据的可验证凭据出示信息(Verifiable Presentation, VP),并提交给验证方。 示例代码: ```Java import com.rep.vc.roles.VCHolder; import com.rep.vc.models.vp.VPMetadata; import com.rep.vc.models.vp.VerifiablePresentation; ...... // 凭据持有者did String holderDid = "did:rep:example:456" // 凭据持有者本次操作所用证书名称 String holderCertName = "holder-1" // 凭据持有者本次操作所用私钥(pem格式字符串,也可为PrivateKey对象) String holderPrvKey = "-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGByq........\n-----END PRIVATE KEY-----"; VCHolder holder = new VCHolder(holderDid, holderCertName, holderPrvKey); // 可验证凭据出示元数据 VPMetadata meta = new VPMetadata(); meta.addType("UniversityDegreePresentation"); meta.setId("0x123456abcdefg"); // 凭据持有者创建可验证凭据出示对象 // 使用验证方提供的签名挑战信息 VerifiablePresentation vp = holder.present(meta, vcFromJson, SignatureTools.ECSecp256k1Sig, "challenge-bcdhjs"); /* * 也可一次出示多个可验证凭据 * List vcList = new ArrayList<>(); * vcList.add(vc1); * vcList.add(vc2); * VerifiablePresentation vp = holder.present(meta, vcList, SignatureTools.ECSecp256k1Sig, "challenge-bcdhjs"); */ // 将可验证凭据出示对象序列化为Json字符串 String vpJson = vp.exportAsJsonStr(); /* * Json格式VP示例: * { * "@context": [ "https://www.w3.org/2018/credentials/v1" ], * "id": "0x123456abcdefg", * "type": [ "VerifiablePresentation","UniversityDegreePresentation" ], * "holder": "did:rep:example:456", * "verifiableCredential": { * "@context": [ "https://www.w3.org/2018/credentials/v1" ], * "id": "0x123456", * "type": [ "VerifiableCredential","UniversityDegreeCredential" ], * "claimScheme": "CCS-001", * "issuer": "did:rep:example:123", * "issued": "2021-03-26T10:08:09Z", * "validFrom": "2021-03-26T10:08:59Z", * "validUntil": "2022-03-26T10:08:59Z", * "credentialSubject": { * "0": { "serialNumber": "2021063012342176" }, * "1": { "id": "did:rep:example:987654" }, * "2": { "name": "Tom" }, * "3": { "degree": "Master" }, * "4": { "date": "2021-06-30"}, * "5": { "university": "RepChain Training University" } * }, * "proof": { * "type": "EcdsaSecp256k1Signature", * "created": "2021-03-26T10:09:00.719Z", * "verificationMethod": "did:rep:example:123#issuer-1", * "signature": { * "0": "MEUCIQDheXVNMujuV42jFx/CrhNm0zJQguLJV6IDBg7ttxbq4AIgYGJeY73CYT55WSwXWdDnjXjXEBK/pnYNs8bq77MbRJM=", * "1": "MEQCIGZElCFmhcXB9T42lYQ+qNcBkJbhCHxvCZ3SkjXUelzDAiA9bt1KoMZT+NAT3bo70gLMTEba3r+2r0erAG8nchVUSQ==", * "2": "MEQCIF7GpDod/y57h0LPzwt7mVI+XbRspGh4nHv2WWlU+yLUAiAulP/D/0fojwmUofOnACfu2Bo6vz462Ire61rtuIJ4jg==", * "3": "MEUCIQCi/0aZdVcgFn/6La9zRAFgyM86Dup6aocVAIpXNBVSAAIgHM+arEn1lK0q52CNmuq/aHtJDnTDOukACQ54cVE9pco=", * "4": "MEUCIAglrY2LpemyEh62reRHgBtez/7roxi2+w9Y4NRWlfAnAiEAmOqq7+2w1dA2MxzSpsfs6ua0l3OWt7oCr7N+eab1/Zs=", * "5": "MEQCIGxyKXSRIQmiYmAe2gRldr/UXTi9+j2Onv2QuFeGw/bWAiBRadb5+JrX7IBhuHs+pKvw5dvNO1dI3Mlb1/spW3LExw==" * } * } * }, * "proof": { * "type": "EcdsaSecp256k1Signature", * "created":"2021-04-12T06:40:16.386Z", * "verificationMethod": "did:rep:example:456#hoder-1", * "challenge":"challenge-bcdhjs", * "signature":"MEQCIFty53B+xeahWQdYzulvOye09C4ozXlYx4iEqFmb49KfAiBKDpIuZO8g4DQNnr46k/1cFi3/3DgdvAgYCAaGJ5/4Dg==" * } * } */ ``` #### 选择性披露可验证凭据属性 基于对隐私保护的考量,用户可以根据验证方的具体需求,选择性地尽可能最小化披露自己持有的可验证凭据信息。 示例代码: ```Java import com.rep.vc.models.vc.VerifiableCredential; import com.rep.vc.models.vp.VPMetadata; import com.rep.vc.models.vp.VerifiablePresentation; ...... // 可根据属性名称或属性编号选择性披露可验证凭据属性信息 // 避免非必要隐私信息的泄露 String[] name = new String[]{"name", "id", "degree"}; VerifiableCredential disclosedVC = holder.discloseClaimsByName(vc, name); // 可验证凭据出示元数据 VPMetadata metaSelectiveDisclosed = new VPMetadata(); metaSelectiveDisclosed.addType("UniversityDegreePresentation"); metaSelectiveDisclosed.setId("0x23456abcdefgh"); // 凭据持有者创建可验证凭据出示对象 // 使用验证方提供的签名挑战信息 VerifiablePresentation vpWithSelectiveDisclosedVC = holder.present(metaSelectiveDisclosed, disclosedVC, SignatureTools.ECSecp256k1Sig, "challenge-sjdsjk"); ``` #### 序列化和反序列化可验证凭据出示 可将可验证凭据出示对象序列化为Json字符串或二进制数据,以方便传递给验证方。 示例代码: ```Java // 序列化为Json字符串 String vpJson = vp.exportAsJsonStr(); // 序列化为二进制数据 byte[] vpBytes = vp.exportAsBytes(); ``` 验证方获取到序列化后的可验证凭据出示信息后,需对其进行反序列化,以方便对进行验证等操作。 示例代码: ```Java import com.rep.vc.models.vc.VerifiablePresentation; // 反序列化Json字符串格式数据 VerifiablePresentation vpFromJson = VerifiablePresentation.parseFrom(vpJson); // 反序列化二进制格式数据 VerifiablePresentation vpFromBytes = VerifiablePresentation.parseFrom(vpBytes); ``` #### 验证可验证凭据 凭据验证方作为可验证凭据验证者,可对接收到的可验证凭据出示信息及其包含的可验证凭据进行验证。 示例代码: ```Java // 凭据验证者did String verifierDid = "did:rep:example:789" // 凭据验证者本次操作所用证书名称 String verifierCertName = "verifier-1" // 凭据验证者本次操作所用私钥(pem格式字符串,也可为PrivateKey对象) String verifierPrvKey = "-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGByq........\n-----END PRIVATE KEY-----"; VCVerifier verifier = new VCVerifier(verifierDid, verifierCertName, verifierPrvKey); // 期望凭据处于的目标状态,其顺序应与可验证凭据出示信息中包含的可验证凭据的顺序一致 String[] targetStatus = new String[]{"VALID"}; // 凭据验证方自己之前提供给凭据持有者的签名挑战信息 String targetChallenge = "challenge-bcdhjs"; // 验证结果 boolean res = verifier.verify(vpFromBytes, targetChallenge, targetStatus); ```