Affinidi Messaging

A secure and verifiable communication between sender and receiver that enhances trust in digital communications.

GitHub Repository

Affinidi Messaging leverages the DIDComm Messaging protocol, built on top of the decentralised design of a Decentralised Identifier (DID) for secure and privacy-preserving digital communication.

DIDComm Messaging provides a mechanism for exchanging messages between entities using a Decentralised Identifier (DID), utilising public key cryptography. It ensures the confidentiality, integrity, and authenticity of the communication sent within the network and establishes trust.

Affinidi Messaging is an open-source project built using Rust programming language and published on GitHub, including the  Affinidi DID Resolver; a high-performance DID resolver with caching. You can deploy and run the Affinidi Messaging, and Affinidi DID Resolver in your local environment by following these steps using the published  Rust crates.

Benefits of Affinidi Messaging

By following the DIDComm Messaging protocol, Affinidi Messaging offers the following benefits when sending messages:

Enhanced User Trust and Privacy: Using Decentralised Identifier (DID), it utilises public key cryptography to secure the privacy and confidentiality of the messages establishing trust on digital communication.

Improved Security and Authenticity: It enables verifiability of the communication using digital signatures, ensuring that the message sent within the network is authentic and tamper-evident.

Interoperability & Flexibility: Support any DID-based platforms for secure communication, which can be adapted to various use cases, such as issuing and sharing Verifiable Credentials (VCs).

How Affinidi Messaging Works

To communicate securely with another user using Affinidi Messaging, the user must obtain the recipient’s Decentralised Identifier (DID). This is used to securely transport and verify the authenticity of the message.

Refer to the diagrams below to learn more about how sending and receiving messages works.

Sending Message

Once the sender composes the desired message, Affinidi Messaging resolves the recipient’s DID to obtain the public key. This public key is used to encrypt the message, ensuring that only the intended recipient can read the message’s raw content.

Before sending the message, it is signed with the sender’s private key securely stored on the sender’s local device to enable the recipient to verify its authenticity. Once the message is encrypted and signed, the data is sent to Affinidi Messaging’s Mediator service to securely store it for later processing and retrieval by the recipient.

sequenceDiagram
    autonumber
    actor Sender
    participant SDK as Affinidi Messaging - SDK
    participant AMR as Affinidi DID Resolver
    participant AMM as Affinidi Messaging - Mediator

    Sender->>SDK: Compose the message
    SDK->>AMR: Resolve recipient's DID to obtain public key
    AMR->>AMR: Resolves DIDs to extract DID document
    AMR->>SDK: Returns DID document and key info of the recipient
    SDK->>SDK: Encrypts the message using the recipient's public key
    SDK->>SDK: Signs the encrypted data
    Note over SDK, SDK: Using the Sender's private key locally stored on their device
    SDK->>AMM: Send the encrypted blob message to the mediator for storing

Receiving Message

The Affinidi Messaging SDK queries the Mediator to determine if a message is available for the current user and retrieves it. Then, the Affinidi Messaging resolves the sender’s DID to obtain a public key to verify the message’s authenticity. After verifying the message’s authenticity, the message is decrypted using the recipient’s private key securely stored on the recipient’s local device to read the raw message.

sequenceDiagram
    autonumber
    actor Recipient
    participant SDK as Affinidi Messaging - SDK
    participant AMR as Affinidi DID Resolver
    participant AMM as Affinidi Messaging - Mediator

    AMM->>SDK: Parse the message intended for the current recipient
    SDK->>AMR: Resolve sender's DID to obtain public key
    AMR->>AMR: Resolves DIDs to extract DID document
    AMR->>SDK: Returns DID document and key info of the sender
    SDK->>SDK: Verifies authenticity of the message
    Note over SDK, SDK: Using the public key of the sender
    SDK->>SDK: Decrypts the encrypted data
    Note over SDK, SDK: Using the recipient's private key stored locally on their device
    SDK->>Recipient: Reads the message

Supported DID Methods

Affinidi Messaging supports the following DID methods for sending and receiving messages.

  • did:key
  • did:peer
  • did:web
  • did:ethr
  • did:jwk
  • did:pkh

Running Affinidi Messaging Locally

Running the mediator requires these packages, which are also part of the Affinidi Messaging project.

  • affinidi-messaging-didcomm - Affinidi Messaging DIDComm implementation, a modified version of didcomm-rust project. The source code is published here.
  • affinidi-messaging-sdk - a Software Development Kit (SDK) to simplify the implementation of Affinidi Messaging into your application. The source code is published here.

Affinidi Messaging also depends on the following Rust crates as part of the Affinidi DID Resolver:

  • affinidi-did-resolver-cache-sdk - a high-performance DID resolver with the caching mechanism for DID documents. It is published on crates.io, and the source code is published here.

  • did-peer - part of the Affinidi DID Resolver for did:peer generation and resolution. It is published on crates.io, and the source code is published here.

Prerequisites

To build and run this Affinidi Messaging project, you need to set up the following:

  1. Install Rust on your machine if you haven’t installed it yet using this guide.

  2. Install the Docker on your machine if you haven’t installed it yet using this guide. We will need this to run Redis instance for the mediator.

  3. Make sure you have Git installed on your machine. Follow this guide on how to install Git.

Running the Mediator Service

  1. Clone the Affinidi Messaging repository. Use this guide to know how to clone a repo from GitHub.

  2. Run a Redis docker container using the command below.

    docker run --name=redis-local --publish=6379:6379 --hostname=redis --restart=on-failure --detach redis:latest
  3. Inside the affinidi-messaging cloned repository, navigate to the affinidi-messaging-mediator subfolder on your terminal to create certificates for the mediator.

    Create server, intermediate, client and Root Certificate Authority keys and certs.

    cd affinidi-messaging-mediator
    cargo run --example create_local_certs

    This will generate certificate files in the affinidi-messaging-mediator/conf/keys folder. If you intend to create a new script, you should use client.chain file to override the default SSL certificates in affinidi-messaging-sdk, like:

    let mut config = Config::builder()
    .with_ssl_certificates(&mut vec![
        "../affinidi-messaging-mediator/conf/keys/client.chain".into()
    ])

    Refer to Affinidi Messaging SDK examples for the sample code to override default SDK SSL certificates.

  4. In the same affinidi-messaging-mediator subfolder, run the following command to generate DID and corresponding keys.

    cargo run --example generate_secrets

    This will generate affinidi-messaging-mediator/conf/secrets.json-generated file containing a did:peer together with the pair of keys for verification and encryption. Use the generated did:peer as a value for <MEDIATOR_DID> placeholder in following commands as well as in Affinidi Messaging SDK Examples.

  5. Save the generated affinidi-messaging-mediator/conf/secrets.json-generated file as affinidi-messaging-mediator/conf/secrets.json.

  6. Start the affinidi-messaging-mediator using the folowing command.

    cd affinidi-messaging-mediator
    export MEDIATOR_DID=did://<MEDIATOR_DID>
    export REDIS_URL=redis://@localhost:6379
    cargo run

    Replace the <MEDIATOR_DID> with the did:peer value generated from Step 4.

Running Sample Code

Explore the affinidi-messaging-sdk examples folder provided in the affinidi-messaging repository to run the available sample codes.

To run the Affinidi Messaging SDK examples, use the following command:

cd affinidi-messaging-sdk
# enable logging for examples,
export RUST_LOG=none,affinidi_messaging_sdk=debug,ping=debug,demo=debug,send_message_to_me=debug,send_message_to_bob=debug,fetch_message_as_bob=debug,message_pickup=debug
# no "did://" prefix for examples
export MEDIATOR_DID=<MEDIATOR_DID>
# default, local mediator endpoint
export MEDIATOR_ENDPOINT=https://localhost:7037/mediator/v1
# relative path to local mediator cert file
export MEDIATOR_TLS_CERTIFICATES="../affinidi-messaging-mediator/conf/keys/client.chain"

# send a trust ping
cargo run --example ping -- \
  --network-address $MEDIATOR_ENDPOINT \
  --ssl-certificates $MEDIATOR_TLS_CERTIFICATES \

Additional Resources

Quickly start and learn more about Affinidi Messaging using sample codes and Affinidi Messaging SDK.


Sample Codes

Sample codes to implement Affinidi Messaging with your application.

Affinidi Messaging SDK

Quickly implement decentralised communication with Affinidi Messaging using the SDK.