Swift library for DIDComm V2 protocol with message encryption/decryption, signing, DID authentication, and advanced routing for secure, decentralized communication.
DIDCommV2 is a comprehensive Swift package designed to facilitate the development of applications utilizing the Decentralized Identity Communication (DIDComm) V2 protocol. It offers Swift developers a robust toolkit for building secure, private communication systems based on decentralized identities.
To integrate DIDCommV2 into your Xcode project using SPM, specify it in your Package.swift:
dependencies: [
.package(url: "https://github.com/beatt83/didcomm-swift.git", .upToNextMajor(from: "0.1.0"))
]
Envelopes |
|
---|
Algorithms |
|
---|
Encryption Algorithms | Keys Algorithms |
|
|
---|
Encryption Algorithms | Keys Algorithms |
|
|
---|
|
The DIDCommV2 Swift Package facilitates creating and processing various types of DIDComm messages, such as plain, signed, and encrypted (both authenticated and anonymous) messages. Here’s how to utilize the package for these scenarios:
let didcomm = DIDComm(
didResolver: // ... DID Resolver implementation,
secretResolver: // ... Secret Resolver implementation
)
let packed = try await didcomm.packPlainText(params: .init(
message: // ... Message
))
let unpacked = try await didcomm.unpack(params: .init(packedMessage: packed.packedMessage))
// Utilize `unpacked.message` as needed
let didcomm = DIDComm(
didResolver: // ... DID Resolver implementation,
secretResolver: // ... Secret Resolver implementation
)
let packed = try await didcomm.packSigned(params: .init(
message: // ... Message,
signFrom: "did:example:alice#key-3" // Replace with actual signer DID Key ID
))
let unpack = try await didcomm.unpack(params: .init(packedMessage: packed.packedMessage))
// Validate `unpack.message` as needed
let didcomm = DIDComm(
didResolver: // ... DID Resolver implementation,
secretResolver: // ... Secret Resolver implementation
)
let packed = try await didcomm.packEncrypted(params: .init(
message: // ... Message,
to: ["did:example:charlie"], // Replace with recipient DID
from: "did:example:alice", // Replace with sender DID
encAlgAuth: .a256CBCHS512
))
let didcommUnpack = DIDComm(
didResolver: // ... recipient DID Resolver implementation,
secretResolver: // ... recipient Secret Resolver implementation
)
let unpacked = try await didcommUnpack.unpack(params: .init(packedMessage: packed.packedMessage))
// Verify `unpacked.message` content
let didcomm = DIDComm(
didResolver: // ... DID Resolver implementation,
secretResolver: // ... Secret Resolver implementation
)
let packed = try await didcomm.packEncrypted(params: .init(
message: // ... Message,
to: ["did:example:charlie"], // Replace with recipient DID
encAlgAnon: .a256GCM // Assuming A256GCM is supported for anonymous encryption
))
let didcommUnpack = DIDComm(
didResolver: // ... recipient DID Resolver implementation,
secretResolver: // ... recipient Secret Resolver implementation
)
let unpacked = try await didcommUnpack.unpack(params: .init(packedMessage: packed.packedMessage))
// Validate `unpacked.message` content
In DIDComm, messages can be delivered to their final destination through a series of mediators. This process, known as routing, involves wrapping the original message in a series of forward messages for each mediator in the path.
The DIDCommV2 Swift SDK simplifies the handling of routing with the RoutingResult structure. When you pack a message for encryption or signing, the SDK can process and return a RoutingResult that contains the necessary forward messages along with the mediators’ information.
Each ForwardMessageResult within the RoutingResult holds:
The SDK ensures that only necessary forward messages are generated and retrieved, avoiding redundant routing steps.
The diagram below illustrates the DIDComm message routing process. It demonstrates how a message for Bob DID is securely forwarded through a series of mediators before reaching the final recipient. Each mediator receives a forward message containing the next mediator’s DID or the final recipient’s DID, ensuring that the message is reliably transmitted along the specified path.
Forward Message 1 is sent to Bob Mediator 1, which in turn forwards Forward Message 2 to Bob Mediator 2. From there, two branches occur: Forward Message 3 is sent directly to Bob Mediator 3 with a specific routing key, while Forward Message 4 is re-routed through Bob Mediator 2 using a different routing key. This example showcases the flexibility of DIDComm’s routing mechanism to support complex message delivery scenarios.
The following is an example of how you can pack a message that needs to be routed through mediators and then send the forward messages to the appropriate mediators:
/ Initialize the DIDComm instance with your resolver implementations
let didcomm = DIDComm(
didResolver: // ... Your DID Resolver implementation,
secretResolver: // ... Your Secret Resolver implementation
)
// Pack an encrypted message with routing
let packed = try await didcomm.packEncrypted(params: .init(
message: // ... Your Message object,
to: ["did:example:bob"], // Bob's DID
from: "did:example:alice", // Alice's DID (optional)
encAlgAuth: .a256CBCHS512 // Authenticated encryption algorithm
))
// If there's routing involved, process the forward messages
if let routingResults = packed.routingResult {
for forwardMessageResult in routingResults.forwardMessages {
// Here you would send `forwardMessageResult.forwardMessage.packedMessage`
// to the mediator `forwardMessageResult.routedBy`
// The actual sending mechanism would depend on your transport layer
}
}
You can access here to the documentation.
We highly appreciate community contributions. To contribute, please fork the repository, push your changes, and open a pull request.
This project is licensed under the Apache 2.0 License.