# Class RoomKeyProtector | EchoHub Documentation
Encrypts cached room content keys at rest so the client config never holds them as plain base64. Windows uses DPAPI (current-user scope, format prefix &quot;dp1:&quot;). On other platforms the keys are AES-GCM encrypted with a per-user master key file stored next to the config with 0600 permissions (prefix &quot;k1:&quot;) — without an OS keychain that is file-permission-level protection, not zero-knowledge: anyone who can read both the config and the key file can recover the room keys. Values with no recognized prefix are legacy plain-base64 keys from older clients; they load once and are [cut: 666 characters, first 596 kept]

# Class RoomKeyProtector

Namespace
  EchoHub.Client.Services

Assembly
  EchoHub.Client.dll

Encrypts cached room content keys at rest so the client config never holds them as plain base64. Windows uses DPAPI (current-user scope, format prefix "dp1:"). On other platforms the keys are AES-GCM encrypted with a per-user master key file stored next to the config with 0600 permissions (prefix "k1:") — without an OS keychain that is file-permission-level protection, not zero-knowledge: anyone who can read both the config and the key file can recover the room keys. Values with no recognized prefix are legacy plain-base64 keys from older clients; they load once and are re-encrypted. The room passphrase itself is never stored in any form.

    public sealed class RoomKeyProtector

Inheritance
  object
  RoomKeyProtector

Inherited Members
  object.GetType()
  object.ToString()
  object.Equals(object)
  object.Equals(object, object)
  object.ReferenceEquals(object, object)
  object.GetHashCode()

## Constructors

### RoomKeyProtector(string, bool?)

    public RoomKeyProtector(string keyDirectory, bool? useDpapi = null)

#### Parameters

`keyDirectory` string

  Directory holding the master key file (the client config dir).

`useDpapi` bool?

  Overrides the platform default (DPAPI on Windows) — for tests.

## Fields

### DpapiPrefix

    public const string DpapiPrefix = "dp1:"

#### Field Value

string

### KeyFilePrefix

    public const string KeyFilePrefix = "k1:"

#### Field Value

string

## Methods

### Protect(byte[])

Encrypts a room key for storage in the config file.

    public string Protect(byte[] roomKey)

#### Parameters

`roomKey` byte[]

#### Returns

string

### TryUnprotect(string, out byte[], out bool)

Decrypts a stored value back into a room key. `wasLegacy` is true when the value was an unencrypted legacy entry that should be re-persisted via Protect(byte[]). Returns false for unreadable values (wrong user/machine, missing or regenerated key file, malformed data) — the caller drops the entry and the user can recover it by re-entering the passphrase.

    public bool TryUnprotect(string stored, out byte[] roomKey, out bool wasLegacy)

#### Parameters

`stored` string
`roomKey` byte[]
`wasLegacy` bool

#### Returns

bool