1个不稳定发布

0.3.0 2022年5月6日

#529 in 身份验证


vade-evan中使用

自定义许可证

195KB
4K SLoC

vaedidcomm

关于

这个crate是一个DIDComm V2 vade插件,目前提供

  • 使用DIDComm rs进行消息加密和解密
  • 通过DIDComm消息type支持协议

它实现了以下VadePlugin函数

当前支持的协议

用法

didcomm_send为发送给接收者的消息做准备,didcomm_receive用于解密和分析传入的消息。默认情况下,每个发送的消息都将被加密,要么使用与通信伙伴现有的DID交换中保存的加密密钥,要么使用提供的密钥。特定的协议类型可以覆盖消息的加密设置,仅发送普通消息(如DID交换)。

注意:当您发送任何将加密的消息时,您需要有一个完成的DID交换或正确的加密密钥,这些密钥被传递给vade_didcomm。

这两个函数didcomm_senddidcomm_receive可以带两个参数调用,optionsmessage

  • 选项:包含传递特殊配置到vade_didcomm的特定信息。目前它只是用于注入特定的加密配置,以覆盖默认的DIDComm DID交换密钥加密和签名。
{
  "encryptionKeys": {
    "encryptionMySecret": "...",
    "encryptionOthersPublic": "..."
  },
  "signingKeys": {
    "signingMySecret": "...",
    "signingOthersPublic": "..."
  }
}
  • 消息:包含至少类型、到DID和从DID的普通消息对象。

这两个函数的结果都将始终返回结构几乎相同的字符串化JSON,唯一不同的是 didcomm_receive 不返回 messageRaw 属性,返回模式如下:

didcomm_send

{
  "message": {},
  "messageRaw": {},
  "metadata": {}
}

didcomm_receive

{
  "message": {},
  "metadata": {}
}

messagemetadata 中表示的数据是协议特定的。消息也作为未加密的 messageRaw 附加。

信任ping

此协议实现只有2步,更像是测试协议。要发送 trust_ping 消息,将以下消息传递给 didcomm_send

{
    "type": "https://didcomm.org/trust_ping/1.0/ping",
    "from": "did::xyz:34r3cu403hnth03r49g01",
    "to": [ "did::xyz:34r3cu403hnth03r49g03" ],
}

这将返回一个加密的字符串化消息,并在消息中添加一个包含以下内容的正文:

{
  "body": {
    "response_requested": true
  }
}

did_exchange

DID 交换协议 相对复杂,包含3个步骤。整个流程在 did-exchange test 中实现。像 trust_ping 一样,您可以传递一个简单的消息,该消息将被增强为实际发送的数据。以下是一个第一请求的示例(确保将 service_endpoint 设置为您的 DID 代理可用的 URL)

{
  "type": "https://didcomm.org/didexchange/1.0/request",
  "service_endpoint": "https://evan.network",
  "from": "did:uknow:d34db33d",
  "to": ["did:uknow:d34db33f"]
}

这将返回以下结果:

{
  "message": {
    "body": {
      "@context": "https://w3id.org/did/v1",
      "authentication": [
        "{0}#key-1"
      ],
      "id": "did:uknow:d34db33d",
      "publicKey": [
        {
          "id": "did:uknow:d34db33d#key-1",
          "publicKeyBase58": "b1f88eebc9576fcb923837d9455ffd24a2c634d95e4e7c9fdf0ab362fd092a7c",
          "type": [
            "Ed25519VerificationKey2018"
          ]
        }
      ],
      "service": [
        {
          "id": "did:uknow:d34db33d#didcomm",
          "priority": 0,
          "recipientKeys": [
            "b1f88eebc9576fcb923837d9455ffd24a2c634d95e4e7c9fdf0ab362fd092a7c"
          ],
          "serviceEndpoint": "",
          "type": "did-communication"
        }
      ]
    },
    "from": "did:uknow:d34db33d",
    "id": "de9358ae810341e6b02bc08f7fd061ec",
    "pthid": "de9358ae810341e6b02bc08f7fd061ec#key-1",
    "thid": "did:uknow:d34db33d#key-1",
    "to": [
      "did:uknow:d34db33f"
    ],
    "type": "https://didcomm.org/didexchange/1.0/request"
  },
  "metadata": {
    "pub_key": "b1f88eebc9576fcb923837d9455ffd24a2c634d95e4e7c9fdf0ab362fd092a7c",
    "secret_key": "487db1e4be6f0ec0cb4fa07a64a5aea9bd5e77ba8f639e8595563535c5784166",
    "target_pub_key": "",
    "target_service_endpoint": ""
  }
}

如你所见,整个消息都被 enrich 了进行 DID 交换所需的数据。元数据包含生成的通信十六进制编码的公钥和私钥。接收者只需将整个 JSON 传递给 didcomm_receive 函数,该函数将分析消息,保存通信密钥,并为自身生成新的密钥。接收者然后可以使用发送响应的逻辑,只需替换消息类型 https://didcomm.org/didexchange/1.0/response.

提供证据协议

提供证明协议 由 4 个步骤组成。整个流程在 present-proof test 中实现。一般的流程开始于验证者向证明者发送 request-presentation 消息。证明者可以选择用请求的证明回答,或者向验证者提出一个新的证明。 request-presentation 的格式如下:

{
    "@type": "https://didcomm.org/present-proof/1.0/request-presentation",
    "@id": "<uuid-request>",
    "comment": "some comment",
    "request_presentations~attach": [
        {
            "@id": "libindy-request-presentation-0",
            "mime-type": "application/json",
            "data":  {
                "base64": "<bytes for base64>"
            }
        }
    ]
}

证明者然后以 presentationpropose-presentation 消息进行响应。以下是为这些消息的格式:

提供响应格式

{
    "@type": "https://didcomm.org/present-proof/1.0/presentation",
    "@id": "<uuid-presentation>",
    "comment": "some comment",
    "presentations~attach": [
        {
            "@id": "libindy-presentation-0",
            "mime-type": "application/json",
            "data": {
                "base64": "<bytes for base64>"
            }
        }
    ]
}

提供提议格式

{
    "@type": "https://didcomm.org/present-proof/1.0/presentation-preview",
    "attributes": [
        {
            "name": "<attribute_name>",
            "cred_def_id": "<cred_def_id>",
            "mime-type": "<type>",
            "value": "<value>",
            "referent": "<referent>"
        },
        // more attributes
    ],
    "predicates": [
        {
            "name": "<attribute_name>",
            "cred_def_id": "<cred_def_id>",
            "predicate": "<predicate>",
            "threshold": "<threshold>"
        },
        // more predicates
    ]
}

一旦完成提供交换,验证者向证明者发送一个确认消息,以确认已接收并验证接收到的证明数据。

颁发凭证协议

颁发凭证协议 由 5 个步骤组成。整个流程在 issue-credential test 中实现。一般的流程开始于持有者向颁发者发送 propose-credential 消息。颁发者可以选择用 offer-credential 进行回答,或者用 problem-report 消息终止请求。持有者收到 offer-credential 并决定发送 request-credential 消息。一旦颁发者收到 request-credential,他/她就会响应 issue-credential,持有者将接收并发送 ack 消息以确认凭证的接收。

提议凭证消息

{
    "@type": "https://didcomm.org/issue-credential/1.1/propose-credential",
    "@id": "<uuid-of-propose-message>",
    "comment": "some comment",
    "credential_proposal": "<json-ld object>",
    "schema_issuer_did": "DID of the proposed schema issuer",
    "schema_id": "Schema ID string",
    "schema_name": "Schema name string",
    "schema_version": "Schema version string",
    "cred_def_id": "Credential Definition ID string",
    "issuer_did": "DID of the proposed issuer"
}

提供凭证消息

{
    "@type": "https://didcomm.org/issue-credential/1.0/offer-credential",
    "@id": "<uuid-of-offer-message>",
    "comment": "some comment",
    "credential_preview": "<json-ld object>",
    "offers~attach": [
        {
            "@id": "libindy-cred-offer-0",
            "mime-type": "application/json",
            "data": {
                "base64": "<bytes for base64>"
            }
        }
    ]
}

请求凭证消息

{
    "@type": "https://didcomm.org/issue-credential/1.0/request-credential",
    "@id": "<uuid-of-request-message>",
    "comment": "some comment",
    "requests~attach": [
        {
            "@id": "attachment id",
            "mime-type": "application/json",
            "data": {
                "base64": "<bytes for base64>"
            }
        },
    ]
}

颁发凭证消息

{
    "@type": "https://didcomm.org/issue-credential/1.0/issue-credential",
    "@id": "<uuid-of-issue-message>",
    "comment": "some comment",
    "credentials~attach": [
        {
            "@id": "libindy-cred-0",
            "mime-type": "application/json",
            "data": {
                "base64": "<bytes for base64>"
            }
        }
    ]
}

提供交换协议

《展示交换协议》(Presentation Exchange Protocol)包含3个步骤。整个流程在presentation-exchange test中实现。通用流程从验证者向持有者发送request-presentation消息开始。持有者可以选择回复propose-presentation或发送presentation消息。一旦验证者收到presentation消息,他/她将匹配收到的凭证声明与presentation-definition请求,并使用presentation-definition中的input-descriptors数组中的约束来验证声明的值。

在当前展示交换协议的实现中,由于约束非常多样且针对特定应用需求,json模式约束必须由使用vade的客户端应用程序验证,有关约束的详细信息,请访问Presentation Exchange Protocol

request-presentation消息

{
    "options": {
        "challenge": "...",
        "domain": "...",
    },
    "presentation_definition": {
        // presentation definition object
    }
}

presentation-definition示例

{
  "comment": "Note: VP, OIDC, DIDComm, or CHAPI outer wrapper would be here.",
  "presentation_definition": {
    "id": "32f54163-7166-48f1-93d8-ff217bdb0653",
    "input_descriptors": [
      {
        "id": "wa_driver_license",
        "name": "Washington State Business License",
        "purpose": "We can only allow licensed Washington State business representatives into the WA Business Conference",
        "schema": [{
            "uri": "https://licenses.example.com/business-license.json"
        }]
      }
    ]
  }
}

presentation消息示例

{
    "@type": "https://didcomm.org/present-proof/%VER/presentation",
    "@id": "f1ca8245-ab2d-4d9c-8d7d-94bf310314ef",
    "comment": "some comment",
    "formats" : [{
        "attach_id" : "2a3f1c4c-623c-44e6-b159-179048c51260",
        "format" : "dif/presentation-exchange/[email protected]"
    }],
    "presentations~attach": [{
        "@id": "2a3f1c4c-623c-44e6-b159-179048c51260",
        "mime-type": "application/ld+json",
        "data": {
            "json": {
                "@context": [
                    "https://www.w3.org/2018/credentials/v1",
                    "https://identity.foundation/presentation-exchange/submission/v1"
                ],
                "type": [
                    "VerifiablePresentation",
                    "PresentationSubmission"
                ],
                "presentation_submission": {
                    "descriptor_map": [{
                        "id": "citizenship_input",
                        "path": "$.verifiableCredential.[0]"
                    }]
                },
                "verifiableCredential": [{
                    "@context": "https://www.w3.org/2018/credentials/v1",
                    "id": "https://eu.com/claims/DriversLicense",
                    "type": ["EUDriversLicense"],
                    "issuer": "did:foo:123",
                    "issuanceDate": "2010-01-01T19:73:24Z",
                    "credentialSubject": {
                        "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
                        "license": {
                            "number": "34DGE352",
                            "dob": "07/13/80"
                        }
                    },
                    "proof": {
                        "type": "RsaSignature2018",
                        "created": "2017-06-18T21:19:10Z",
                        "proofPurpose": "assertionMethod",
                        "verificationMethod": "https://example.edu/issuers/keys/1",
                        "jws": "..."
                    }
                }],
                "proof": {
                    "type": "RsaSignature2018",
                    "created": "2018-09-14T21:19:10Z",
                    "proofPurpose": "authentication",
                    "verificationMethod": "did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1",
                    "challenge": "1f44d55f-f161-4938-a659-f8026467f126",
                    "domain": "4jt78h47fh47",
                    "jws": "..."
                }
            }
        }
    }]
}

注册新协议

每个协议都由一系列步骤表示。要注册新协议,只需遵循以下步骤

1. 在src/protocols中添加新文件

该文件可以看起来像以下内容

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct CustomBody {
    custom: Option<bool>,
}

pub fn generate_my_custom_protocol() -> Protocol {
    let mut protocol = Protocol {
        name: String::from("my_custom_protocol"),
        steps: Vec::new(),
    };

    protocol.steps.push(send_step("step1", send_step1));
    protocol.steps.push(receive_step("step1", receive_step1));

    return protocol;
}

pub fn send_step1(_options: &str, message: &str) -> StepResult {
    let mut parsed_message: MessageWithBody<CustomBody> = serde_json::from_str(message)?;
    parsed_message.body = Some(CustomBody {
        response_requested: Some(true),
    });
    return generate_step_output(&serde_json::to_string(&parsed_message)?, "{}");
}

pub fn receive_step1(_options: &str, message: &str) -> StepResult {
    return generate_step_output(message, "{}");
}

2. 在mod.rs文件中导入它

pub(crate) mod my_custom_protocol;

3. 在protocol_handler.rs中注册它

let protocols: [&Protocol; 3] = [
  &generate_did_exchange_protocol(),
  &generate_ping_pong_protocol(),
  &my_custom_protocol(),
];

之后,您只需将以下消息传递给DIDComm函数即可测试您的协议

{
    "type": "my_custom_protocol/step1",
    "from": "did::xyz:34r3cu403hnth03r49g01",
    "to": [ "did::xyz:34r3cu403hnth03r49g03" ],
}

依赖项

~13–32MB
~534K SLoC