Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't use shared secret directly as encryption key #2

Open
G1gg1L3s opened this issue Mar 7, 2025 · 0 comments
Open

Don't use shared secret directly as encryption key #2

G1gg1L3s opened this issue Mar 7, 2025 · 0 comments
Assignees
Labels
bug Something isn't working enhancement New feature or request

Comments

@G1gg1L3s
Copy link

G1gg1L3s commented Mar 7, 2025

Shared secret as encryption key

Hewwo, fren! Just wanted to point out a teeny, fuzzy issue in your project! It looks like the shared secret is being used directly as an encryption key! 🫣

purrcrypt/src/keys.rs

Lines 113 to 116 in 3e43018

let shared_secret = ephemeral_secret.diffie_hellman(recipient_public_key);
// Use shared secret to derive AES key
let aes_key = Key::<Aes256Gcm>::from_slice(shared_secret.raw_secret_bytes());

According to the elliptic-curve docs, raw secrets aren't all that purr-fect for encryption! 🚨

⚠️ WARNING: NOT UNIFORMLY RANDOM! ⚠️

This value is not uniformly random and should not be used directly as a cryptographic key for anything which requires that property (e.g. symmetric ciphers).

Instead, the resulting value should be used as input to a Key Derivation Function (KDF) or cryptographic hash function to produce a symmetric key. The SharedSecret::extract function will do this for you.

A shared secret isn't all snuggly and safe by itself - AES needs it to be uniformly random! If we don't boop it through a KDF first, we're left with a cryptographic weakness (oh no! 😿). Even big-brain cryptography hoomans like NIST recommend always deriving keys properly!

Shared secret as nonce

Oh nyoo! Not only is the shared secret used as a key, but part of it is also being used as a nonce! 😵

let nonce = Nonce::from_slice(&shared_secret.raw_secret_bytes()[..12]);

Reusing key material like this can lead to unexpected cryptographic chaos! 😿

Solution

No need to hiss in distress! 🐍 We can fix this by deriving both the encryption key and nonce properly using a KDF! And guess what? The elliptic curve SharedSecret type already has a built-in API for this! ✨

Here's a pawsome example of how to do it (not tested, but looks fluff-tastic!):

let shared_secret = ephemeral_secret.diffie_hellman(recipient_public_key).extract::<Sha256>();
let mut encryption_key = [0; 32];
let mut nonce = [0; 12];
shared_secret.expand(b"encryption key", &mut encryption_key).expect("length should be ok"); 
shared_secret.expand(b"nonce", &mut nonce).expect("length should be ok"); 

Stay fluffy and secure! 🐾

@vxfemboy vxfemboy self-assigned this Mar 7, 2025
@vxfemboy vxfemboy added bug Something isn't working enhancement New feature or request labels Mar 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants