DIDComm Encryption

View as Markdown

DIDComm v2 envelopes have two crypto layers wrapping the plaintext message:

LayerAlgorithmPurpose
JWS (inner)EdDSA (Ed25519)Authenticity — proves which DID signed
JWE (outer)ECDH-1PU (authcrypt) or ECDH-ES (anoncrypt) + A256GCMConfidentiality — only intended recipients can read
Forward (optional)JWE-only re-wrapRouting via mediator without revealing inner contents

Authcrypt (the IDA default for direct conversations) uses ECDH-1PU, which mixes the sender’s static key with an ephemeral key to give the recipient cryptographic proof of who sent the message. Anoncrypt uses ECDH-ES (ephemeral-only) so the sender DID is hidden from on-path observers and (depending on policy) from the recipient prior to JWS verification.

ModeSender visible to recipient?Sender visible to mediator?Use case
authcryptYes (after unwrap)NoDefault 1:1 messaging
anoncryptNoNoFirst-message bootstrap; whistleblowing
signed-only (no JWE)YesYes (plaintext)Public broadcast, log entries

The platform exposes mode selection via the pack field on service.SendMessageRequest. If omitted, IDA uses authcrypt.

Forward envelopes are JWE-wrapped messages whose plaintext is itself a JWE addressed to the ultimate recipient. The mediator decrypts the outer envelope, learns only “deliver to <recipientKey> at <endpoint>”, and forwards. This pattern is how IDA and external mediators interoperate — see routingKeys in §7.5.

Important: signature verification happens after JWE decryption. If you forge a signature in the inner JWS but the JWE recipient encryption is still valid, the message will decrypt — but the platform will reject the message with RECEIVE_FAILED once JWS verification fails. Never short-circuit signature checks in custom integrations.