repchain-vc-java-sdk,基于RepChain区块链的可验证凭据(Verifiable Credential, VC)SDK(Java语言版)。
我们日常生活中需要使用到各种各样的凭据/证件,比如对于个人而言,会使用到身份证、学位证、护照以及疫苗接种凭证等;对于组织机构而言,需要营业执照等;对于物品而言,可能需要产品合格证及藏品鉴定证等。
可验证凭据(VerifiableCredential,VC)[1]为我们提供了一种以数字化方式来表示及使用凭据的方案,在方便凭据的保存、传输及验证的同时,还为使用者提供了保护其隐私信息的能力。
基于此,我们提出了基于RepChain区块链的可验证凭据应用方案,并在这里为大家提供相应的SDK,希望可以帮助开发者快速实现可验证凭据相关业务逻辑,以支撑其相应业务应用。
可验证凭据的一般使用流程如下图所示:
首先,需要根据具体的业务需求,定义好可验证凭据属性结构(Credential Claims Scheme, CCS),并由特定机构作为凭据属性结构创建者向RepChain区块链注册可验证凭据属性结构CCS。比如在某场景中,需由教育主管部门来定义和创建学位证书的属性结构,或是由质量监督管理部门定义和创建商品合格证的属性结构。基于该属性结构的可验证凭据都应该使用该属性结构来填充属性,并指明其可验证凭据遵循的属性结构。
示例代码如下:
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区块链中注册相应的可验证凭据状态信息,以供后续凭据验证方进行验证。
示例代码如下:
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<String, VCClaim> 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字符串或者二进制数据。
示例代码:
// 序列化为Json字符串
String vcJson = vc.exportAsJsonStr();
// 序列化为二进制数据
byte[] vcBytes = vc.exportAsBytes();
当实体接收到Json字符串格式或二进制格式的可验证凭据时,可以对其进行反解析,以得到相应的可验证凭据对象,方便后续选择性披露属性以及验证有效性等操作。
示例代码:
import com.rep.vc.models.vc.VerifiableCredential;
// 反序列化Json字符串格式数据
VerifiableCredential vcFromJson = VerifiableCredential.parseFrom(vcJson);
// 反序列化二进制格式数据
VerifiableCredential vcFromBytes = VerifiableCredential.parseFrom(vcBytes);
在一般场景下,当用户访问某种业务应用时,应用服务方可能会需要用户提供其持有的相应可验证凭据信息,并对其进行验证。作为凭据持有者,用户需构建包含了相应可验证凭据的可验证凭据出示信息(Verifiable Presentation, VP),并提交给验证方。
示例代码:
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<VerifiableCredential> 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=="
* }
* }
*/
基于对隐私保护的考量,用户可以根据验证方的具体需求,选择性地尽可能最小化披露自己持有的可验证凭据信息。
示例代码:
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字符串或二进制数据,以方便传递给验证方。
示例代码:
// 序列化为Json字符串
String vpJson = vp.exportAsJsonStr();
// 序列化为二进制数据
byte[] vpBytes = vp.exportAsBytes();
验证方获取到序列化后的可验证凭据出示信息后,需对其进行反序列化,以方便对进行验证等操作。
示例代码:
import com.rep.vc.models.vc.VerifiablePresentation;
// 反序列化Json字符串格式数据
VerifiablePresentation vpFromJson = VerifiablePresentation.parseFrom(vpJson);
// 反序列化二进制格式数据
VerifiablePresentation vpFromBytes = VerifiablePresentation.parseFrom(vpBytes);
凭据验证方作为可验证凭据验证者,可对接收到的可验证凭据出示信息及其包含的可验证凭据进行验证。
示例代码:
// 凭据验证者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);
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。