Basic DIDComm v2 support in Python.
pip install didcomm
See https://github.com/sicpa-dlab/didcomm-demo.
SecretsResolver
and DIDResolver
interfaces must be implemented on the application level.
Implementation of that interfaces is out of DIDComm library scope.
SecretsResolver
must match the corresponding key IDs from DID Doc verification methods.did#key-id
.fromPrior
field) is supported.See demo scripts for details.
A general usage of the API is the following:
Message
(plaintext, payload).pack_encrypted
to build an Encrypted DIDComm messagepack_signed
to build a Signed DIDComm messagepack_plaintext
to build a Plaintext DIDComm messageunpack
on receiver side that will decrypt the message, verify signature if needed
and return a Message
for further processing on the application level.This is the most common DIDComm message to be used in most of the applications.
A DIDComm encrypted message is an encrypted JWM (JSON Web Messages) that
It is important in privacy-preserving routing. It is what normally moves over network transports in DIDComm applications, and is the safest format for storing DIDComm data at rest.
See pack_encrypted
documentation for more details.
Authentication encryption example (most common case):
# ALICE
message = Message(
body={"aaa": 1, "bbb": 2},
id="1234567890",
type="my-protocol/1.0",
frm=ALICE_DID,
to=[BOB_DID],
)
pack_result = await pack_encrypted(
resolvers_config=resolvers_config_alice,
message=message,
frm=ALICE_DID,
to=BOB_DID,
pack_config=PackEncryptedConfig(),
)
packed_msg = pack_result.packed_msg
print(f"Sending ${packed_msg} to ${pack_result.service_metadata.service_endpoint}")
# BOB
unpack_result = await unpack(resolvers_config_bob, packed_msg)
print(f"Got ${unpack_result.message} message")
Anonymous encryption example:
message = Message(
body={"aaa": 1, "bbb": 2},
id="1234567890",
type="my-protocol/1.0",
frm=ALICE_DID,
to=[BOB_DID],
)
pack_result = await pack_encrypted(
resolvers_config=resolvers_config_alice,
message=message,
to=BOB_DID,
pack_config=PackEncryptedConfig(),
)
Encryption with non-repudiation example:
message = Message(
body={"aaa": 1, "bbb": 2},
id="1234567890",
type="my-protocol/1.0",
frm=ALICE_DID,
to=[BOB_DID],
)
pack_result = await pack_encrypted(
resolvers_config=resolvers_config_alice,
message=message,
frm=ALICE_DID,
sign_frm=ALICE_DID,
to=BOB_DID,
pack_config=PackEncryptedConfig(),
)
Signed messages are only necessary when
Adding a signature when one is not needed can degrade rather than enhance security because it relinquishes the sender’s ability to speak off the record.
See pack_signed
documentation for more details.
# ALICE
message = Message(
body={"aaa": 1, "bbb": 2},
id="1234567890",
type="my-protocol/1.0",
frm=ALICE_DID,
to=[BOB_DID],
)
pack_result = await pack_signed(
resolvers_config=resolvers_config_alice,
message=message,
sign_frm=ALICE_DID
)
packed_msg = pack_result.packed_msg
print(f"Publishing ${packed_msg}")
# BOB
unpack_result = await unpack(resolvers_config_bob, packed_msg)
print(f"Got ${unpack_result.message} message signed as ${unpack_result.metadata.signed_message}")
A DIDComm message in its plaintext form that
They are therefore not normally transported across security boundaries.
# ALICE
message = Message(
body={"aaa": 1, "bbb": 2},
id="1234567890",
type="my-protocol/1.0",
frm=ALICE_DID,
to=[BOB_DID],
)
pack_result = await pack_plaintext(resolvers_config=resolvers_config_alice, message)
print(f"Publishing ${pack_result.packed_msg}")
# BOB
unpack_result = await unpack(resolvers_config_bob, pack_result.packed_msg)
print(f"Got ${unpack_result.message} message")
PRs are welcome!
The following CI checks are run against every PR: