Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Not going to pretend that I know what the most of the stuff mean, or if it is even safe enough, but I've followed the MDN articles and put together this TypeScript snippet [1]. Maybe somebody could comment on it?

Also sorry for the long link. Is there any accepted way to post a shorted URL?

Edit: added a corrected version [2]

[1]: https://www.typescriptlang.org/play?#code/DYUwLgBAbiDGYHsBOE...

[2]: https://www.typescriptlang.org/play?#code/FAiGGcE8DsGMAIBmBX...



If you call "encrypt" more than once in that code, you'll leak the authentication key. Every invocation of GCM encryption needs a unique nonce. Cryptography nerds will chastise you for using a random nonce (there theoretically isn't enough room in the GCM nonce space to safely encrypt large numbers of message with random nonces), but the alternative (using a counter) is even more hazardous. This problem motivates a lot of people to use other AEADs like XChapoly, which has an extended nonce space that safely admits random nonces. Isn't cryptography fun?


It's still considered safe to call AES-GCM with a single key and a randomly generated nonce 2^32 times [1], most practical systems don't come anywhere near this limit. And there's AES-GCM-SIV that solves nonce reuse (mostly), though it's not available in the Web Cryptography API at the moment.

1: https://csrc.nist.gov/csrc/media/Projects/crypto-publication...


I don't personally care, and probably wouldn't even sev:info a random GCM nonce in an assessment, but I would also choose extended-nonce Chapoly in preference to GCM in part because of this issue.


From what I shallowly researched; GCM's nonce seems limited to 12 bytes by convention only. That nonce reuse is so fatal seems absurd to me.

Would "salting" the key safely tackle the problem?

Put explicitly;

  send <- nonce || salt || ciphertext
  recv -> decrypt(ciphertext, nonce, pbkdf(pass) || salt)
[edit: apply salt outside of the kdf]


As I remember it, the balance of the bytes in the AES block are used for the counter. At any rate, the convention is essentially universal.


Sounds above my (current) head.

Here I thought GCM was some modern foolproof/footgunless design.


It is sort of infamously footgunny.


Oh yes! Thank you for the feedback. I've added a new version where the `iv` and the `salt` is random. Maybe a followup question: Because you need both the `iv` and `salt` to decrypt the message is it ok in an E2E scenario to send all three: `iv`, `salt` and the encrypted message?


I didn't look to see what "salt" means in your design, but the idiom for using GCM in message encryption is to send ciphertexts that take the form `nonce || ciphertext`, and to decrypt by reading the nonce off the front of the message.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: