Table of Contents

Class RoomCrypto

Namespace
EchoHub.Core.Security
Assembly
EchoHub.Core.dll

Client-side envelope encryption for private (end-to-end encrypted) channels.

Design: at creation the client generates a random 256-bit room content key (RCK) that encrypts all room content. The RCK is stored on the server wrapped (AES-GCM encrypted) by a key derived from the passphrase, next to a BCrypt hash of a separately derived auth key used as the join gate. The passphrase, the key-encryption key, and the RCK never leave the client, so the server can gate joins and count/measure content without being able to read it. Changing the passphrase only re-wraps the RCK — history is never re-encrypted.

Derivation: PBKDF2-SHA256(passphrase, salt, 210000 iterations) → 64 bytes; first 32 bytes are the auth key (sent to the server as lowercase hex), last 32 bytes are the key-encryption key (never sent).

public static class RoomCrypto
Inheritance
RoomCrypto
Inherited Members

Fields

CiphertextPrefix

public const string CiphertextPrefix = "$RC1$"

Field Value

string

Methods

DecryptBytes(byte[], byte[])

Decrypts a blob produced by EncryptBytes(byte[], byte[]). Throws System.Security.Cryptography.CryptographicException on key mismatch.

public static byte[] DecryptBytes(byte[] blob, byte[] key)

Parameters

blob byte[]
key byte[]

Returns

byte[]

DeriveKeys(string, byte[])

Derives the auth key (join gate credential) and key-encryption key from a passphrase.

public static RoomCrypto.DerivedKeys DeriveKeys(string passphrase, byte[] salt)

Parameters

passphrase string
salt byte[]

Returns

RoomCrypto.DerivedKeys

EncryptBytes(byte[], byte[])

Encrypts a binary blob (file contents) with the room key: nonce||tag||ciphertext.

public static byte[] EncryptBytes(byte[] plaintext, byte[] key)

Parameters

plaintext byte[]
key byte[]

Returns

byte[]

EncryptText(string, byte[])

Encrypts UTF-8 text with the room key. Output: $RC1$base64(nonce||tag||ciphertext).

public static string EncryptText(string plaintext, byte[] key)

Parameters

plaintext string
key byte[]

Returns

string

GenerateRoomKey()

public static byte[] GenerateRoomKey()

Returns

byte[]

GenerateSalt()

public static byte[] GenerateSalt()

Returns

byte[]

IsRoomCiphertext(string?)

public static bool IsRoomCiphertext(string? content)

Parameters

content string

Returns

bool

TryDecryptText(string, byte[], out string)

Decrypts text produced by EncryptText(string, byte[]). Returns false when the input is not room ciphertext or the key does not match.

public static bool TryDecryptText(string content, byte[] key, out string plaintext)

Parameters

content string
key byte[]
plaintext string

Returns

bool

TryUnwrapRoomKey(string, byte[], out byte[])

Unwraps the stored room content key. Returns false when the KEK (passphrase) is wrong.

public static bool TryUnwrapRoomKey(string wrappedRoomKey, byte[] kek, out byte[] roomKey)

Parameters

wrappedRoomKey string
kek byte[]
roomKey byte[]

Returns

bool

WrapRoomKey(byte[], byte[])

Wraps the room content key under the key-encryption key for server storage.

public static string WrapRoomKey(byte[] roomKey, byte[] kek)

Parameters

roomKey byte[]
kek byte[]

Returns

string