How-to

Verify the multi-party chain

Applies to: .NET SDK Last updated: 2026-06-24

Goal

Inspect the chain of approvers a message passed through and confirm it matches the expected pattern.

Where the chain lives

The plaintext envelope returned by MultiDecryptMessageUsingSharedKeyAsync contains a RECEIVER field — a semicolon-separated list of every party in the chain, in the order the originator specified at encrypt time. There is also a SENDER field identifying the originator.

Code

string plaintextEnvelope = await client.MultiDecryptMessageUsingSharedKeyAsync(
    innerCiphertext, askToOriginator);

// plaintext is a JSON envelope:
// {"REQUEST":"DATAMESSAGE","SENDER":"[email protected]",
//  "RECEIVER":"hr.acme.com;legal.acme.com;[email protected]",
//  "STIME":..., "RTIME":..., "BODY":"approve project X"}

using var doc = JsonDocument.Parse(plaintextEnvelope);
string receiver = doc.RootElement.GetProperty("RECEIVER").GetString() ?? "";
string sender   = doc.RootElement.GetProperty("SENDER").GetString()   ?? "";

string[] chain = receiver.Split(';', StringSplitOptions.RemoveEmptyEntries
                                  | StringSplitOptions.TrimEntries);

Console.WriteLine($"Origin : {sender}");
Console.WriteLine($"Chain  : {string.Join(" -> ", chain)}");

// Application-level check
var expectedApprovers = new[] { "hr.acme.com", "legal.acme.com" };
foreach (var required in expectedApprovers)
{
    if (!chain.Contains(required, StringComparer.OrdinalIgnoreCase))
    {
        Console.WriteLine($"Missing required approver: {required}");
        return;
    }
}

Console.WriteLine("Chain has all required approvers");

What the chain proves

Because the receiver list is bound into the multi-shared key at encrypt time, a chain that decrypts cleanly through every intermediate's DecryptMessageUsingSharedKeyPreAsync and the final MultiDecryptMessageUsingSharedKeyAsync is cryptographically authenticated end to end — a missing or substituted approver fails the peel.

See also