RigoOnRails / encrypted-message

Safely encrypt & store serializable data using XChaCha20Poly1305.
MIT License
3 stars 0 forks source link

Generate more secure nonces #4

Closed RigoOnRails closed 6 months ago

RigoOnRails commented 6 months ago

The nonce generation for Randomized just generates a random byte sequence. Although very, very unlikely, it's still possible for nonces to collide. This would drastically reduce the security of data encrypted with the same key. The nonces should be sequential, & guaranteed to always be unique, not just 99.9999999% of the time.

As for Deterministic, it uses the first 12 bytes of an HMAC-SHA256 hash of the payload, which can also collide.

I'm not sure how I'd implement a counter state easily...

Maybe switch to AES-GCM-SIV?

alcore commented 6 months ago

Aloha,

Maybe switch to AES-SIV?

To touch back on that Reddit context, you probably want https://docs.rs/aes-gcm-siv/latest/aes_gcm_siv/, not AES-SIV. AES-SIV would get you the misuse resistance, but it's slower. AES-GCM-SIV is, slightly simplified, the best of both worlds. However, it's relatively new and there's fewer implementations in various ecosystems, let alone audited ones.

Both have IETF published informational RFCs (which isn't the same as "both are standards" like AES-GCM for TLS is in rfc5288, for example).

RigoOnRails commented 6 months ago

@alcore Awesome! Thanks for that knowledge

alcore commented 6 months ago

Well, that's the easy way out. One of the tradeoffs of SIV is that encryption is about 70% as fast as normal AES-GCM.

You could make your library's use cases stronger - as opposed to someone just using that cipher directly - if you don't take the easier way, though.

I'm not sure how I'd implement a counter state easily

Is your concern regarding the design of the consumer-facing API? The core problems are how to persist that state (and whether the consumer or the library do that), and how to rekey in case the counter gets exhausted (which isn't a realistic issue, given 96-bits of room to work with, albeit this time safely and with no collision chance).

RigoOnRails commented 6 months ago

@alcore Hey, sorry I haven't gotten back to you. I decided to just take the easy route & switch the cipher to XChaCha20Poly1305, for the larger nonce size. I haven't published a new release for it yet.

As I understand it, the chances of a collision with 192 bits are significantly lower than a collision with 96 bits, & is considered "negligible" by most experts.

Let me know what you think!

alcore commented 6 months ago

No worries, and sorry myself.

"Significantly" is an understatement :) A 192-bit collision space is vastly larger. Technically it's still a chance, but yeah, unrealistic.

The underlying ChaCha20 has received less cryptanalysis over the years (basically, due to it being less popular than AES) and AES-NI tends to be faster, but I don't recall ever reading anything about easily exploitable flaws.

RigoOnRails commented 6 months ago

@alcore Awesome! So I guess this is the best way to avoid the troubles of creating 100% unique nonces with AES. Thank you for your input during all of this 😄

I'll still work on making the API cleaner/more intuitive before I try Reddit again