Skip to content

Enhance SafeSecretKey with XOR-based in-memory masking for stronger runtime security #23

@harrytmthy

Description

@harrytmthy

Background

Currently, SafeSecretKey holds the decrypted Data Encryption Key (DEK) directly inside a DirectByteBuffer. While this avoids heap leaks and provides a performance advantage over Java heap storage, the presence of a raw DEK in native memory is still a potential vulnerability. Attackers with memory inspection tools could locate and extract the key, especially in rooted or compromised environments.

Goal

Strengthen in-memory key protection by masking the DEK inside native memory. The masked form should be useless without its corresponding mask, making runtime attacks significantly harder.

Proposed Solution

Instead of storing the raw DEK directly, we will store a masked DEK:

val maskedKey = decryptedKey xor mask
val decryptedKey = maskedKey xor mask

Mask Construction

  • The mask is derived as SHA-256(encryptedDEK).
  • encryptedDEK is the ciphertext of the original DEK stored in noBackupFilesDir, encrypted via a CipherProvider.
  • This mask is deterministic, instance-bound, and never written to disk.

Lifecycle Changes

  • On construction: the decrypted DEK is XOR-ed with the mask and stored off-heap.
  • On getEncoded(): the masked key is XOR-ed with the mask to produce a clone of the original DEK.
  • On releaseHeapCopy(): the clone is wiped from the heap after use.
  • On destroy(): both the masked key and the mask are zeroed out from native memory.

Considerations

  • All operations are constant-time and thread-safe.
  • The mask is not re-generated or time-based, simplifying implementation and ensuring stability across reads.
  • Implementation is backward-compatible, with no changes to encrypted file format or key derivation.

Benefits

  • Full backward compatibility.
  • No runtime or disk format migration required.
  • Dramatically raises the bar for in-memory attacks, while keeping performance overhead negligible.

Metadata

Metadata

Assignees

Labels

Projects

Status

Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions