Encryption & Integrity
Encryption & Integrity
This page provides a complete technical description of how cloud-share encrypts every item and verifies its integrity on arrival.
Overview
Every item queued by the sender goes through the following pipeline before being stored in memory:
flowchart TD
A[Plaintext content] --> B[SHA-512 hash computed]
A --> C["AES-256-GCM encrypt(key, nonce, plaintext)"]
B --> D[Hash stored with item metadata]
C --> E["Payload: nonce 12B || ciphertext || auth tag 16B"]
E --> F[Base64-encode entire payload]
F --> G[Stored in queue, served to receiver]
Key derivation
The AES-256 encryption key is derived from the session secret using SHA-256:
flowchart LR
A["secret\n12-char alphanumeric"] --> B["SHA-256\nUTF-8 bytes of secret"]
B --> C["32-byte key\n256 bits → AES-256 key"]
| Parameter | Value |
|---|---|
| Input | 12-character alphanumeric secret (e.g. aB3kP9mQ2rTs) |
| Hash function | SHA-256 |
| Output | 32 bytes = 256-bit AES key |
This means the key space is determined by the entropy of the 12-character alphanumeric secret. The secret is randomly generated on each sender start, providing a fresh key per session.
ℹ️ Info: SHA-256 is used here for key derivation (a one-way transformation from secret to key), not for integrity. Integrity is handled separately by SHA-512.
AES-256-GCM encryption
Each item is encrypted independently using AES-256-GCM (Galois/Counter Mode):
| Parameter | Value |
|---|---|
| Algorithm | AES-256 |
| Mode | GCM (Galois/Counter Mode) |
| Key size | 256 bits (32 bytes) |
| Nonce size | 96 bits (12 bytes) — randomly generated per item |
| Authentication tag | 128 bits (16 bytes) |
What GCM provides
- Confidentiality: The plaintext is encrypted and cannot be read without the key
- Authenticity: The authentication tag ensures the ciphertext has not been modified. Any tampering invalidates the tag and decryption fails.
- Nonce uniqueness: Each item uses a fresh random 12-byte nonce, ensuring identical plaintexts produce different ciphertexts
Wire format
The encrypted payload stored and transmitted is:
Base64( nonce[12] || ciphertext[N] || auth_tag[16] )
Where || denotes concatenation. The receiver splits off the first 12 bytes as the nonce and the last 16 bytes as the auth tag before passing to the AES-GCM decryption function.
SHA-512 integrity hash
Before encryption, the sender computes a SHA-512 hash of the plaintext:
// Pseudocode
byte[] plaintext = GetContent();
string hash = Convert.ToHexString(SHA512.HashData(plaintext));
// Store hash alongside encrypted item
The hash is stored in the queue item metadata and returned to the receiver alongside the encrypted content.
Why SHA-512?
SHA-512 provides a 512-bit (64-byte) digest. The probability of a collision or a successful preimage attack is negligible. It is used here to detect:
- Accidental corruption during network transfer
- Deliberate tampering with the ciphertext (though GCM already catches this at the transport layer)
- Any modification to the content after encryption
Hash verification on receive
When the receiver downloads an item, it performs the following steps:
flowchart TD
A[Receive encrypted payload] --> B[AES-256-GCM decrypt]
B --> C{Auth tag valid?}
C -- No --> D[❌ FAIL: tampered ciphertext]
C -- Yes --> E[Compute SHA-512 of decrypted plaintext]
E --> F{Hash matches sender metadata?}
F -- Yes --> G[✅ Content intact — deliver to user]
F -- No --> H[❌ Delete item from sender, discard content]
Constant-time comparison
The hash comparison uses a constant-time equality check (equivalent to CryptographicOperations.FixedTimeEquals in .NET). This prevents timing side-channel attacks where an attacker could learn the correct hash value byte-by-byte by measuring comparison duration.
What happens on hash mismatch
A SHA-512 hash mismatch triggers the following response:
- The receiver displays an error in the hash verification modal
- The receiver sends a
DELETE /item/{id}?secret=Xrequest to the sender - The sender permanently removes the item from its queue
- The decrypted content is discarded — never written to disk
- The item cannot be received again from the same sender session
⚠️ Warning: A hash mismatch is a strong signal that something went wrong. In normal operation this should never occur. If you see a mismatch, the sender must re-queue the item.
Transport security
In addition to application-layer encryption:
- All traffic travels over HTTPS through Microsoft Dev Tunnels (TLS 1.2/1.3)
- The Dev Tunnel URL uses
*.devtunnels.mswith a valid TLS certificate - The secret token is transmitted only in HTTPS query parameters (encrypted by TLS)
This provides defense-in-depth: the content is protected by AES-256-GCM at the application layer even if TLS were somehow compromised.
Summary
| Protection | Mechanism |
|---|---|
| Content confidentiality | AES-256-GCM per item |
| Key freshness | New key per sender session (new secret each run) |
| Ciphertext integrity | GCM authentication tag |
| Content integrity | SHA-512 hash, verified by receiver |
| Timing attack prevention | Constant-time hash comparison |
| Transport confidentiality | HTTPS / TLS via Dev Tunnels |
| Zip content (optional) | AES-256 zip entry encryption (SharpZipLib) |