4 ms·
I think this level of key management is relatively simple for a production application. There are not really too many pieces and certainly no unnecessary steps
by mappu 4y ago
I think this level of key management is relatively simple for a production application. There are not really too many pieces and certainly no unnecessary steps (the mitigation recommendation was to add more keys, not fewer).
The interesting part is really just the first step - starting with a user's password, to statically derive a service-authentication key and a data-encryption key that the service provider ostensibly never sees.
At $DAYJOB we independently came up with this same zero-knowledge solution too, using slightly different primitives. Ideally there'd be some well-reviewed zero-footgun nacl.SecretBox()-style thing for this use case, but there simply isn't.
- api 4y agoCryptographers say "don't roll your own," but there is a real poverty of well designed clean easy to use cryptographic libraries that provide well designed building blocks with clear instructions or fully baked well designed protocols. Most cryptographic libraries are arcane and hard to use, and the user experience around things like TLS certificate management is horrible. Most people face a choice between rolling their own crypto or not using it at all.
- tptacek 4y agoIs this true, or is it true of people who don't want to use libsodium, Ring, the Go Seal/Unseal AEAD interface, or KMS because it doesn't feel as cool as inventing your own authentication proof protocol?
- tptacek 4y agoI'm not super entirely clear on how this whole Mega system works, and maybe you understand it better, but is there a reason they couldn't have just run an Augmented PAKE between the client and the server to establish authentication and create a cryptographically secure transport for recovering key blobs, and then used any key-wrap encryption, like AES-SIV, based on any KDF of a password --- ideally a second password --- to encrypt the node keys themselves? There is a whole hellacious amount of mechanism in this protocol that doesn't seem necessary at all. I don't know if doing it simply would involve more keys or less keys but it would certainly seem to involve fewer concepts and less ad-hoc invention --- PAKEs are a solved problem, KDFs are a solved problem, key-wrap encryption is a solved problem. Instead they came up with unpadded RSA, ECB-encrypted key blobs, a single shared key for all the blobs, a post-back proof that is just that broken RSA piped directly back to the server. I don't know, seems pretty bad?
- mappu 4y agoThere's a secure channel here (TLS) and then the blob encryption all happens clientside, so i don't think a PAKE-type solution is less mechanism, but i do recognize your expertise on that. Where do you think it would fit in? Backup and sync-type software has the interesting engineering requirement that it is expected for the user's device to get completely lost/stolen/wiped, so any key material must be reproducible from the user's password. Password -> KDF(1) gives you a password-alike: used for logins, server treats this kdf output as a password and stores a bcrypt/argon hash of it, as you would normally expect from a run-of-the-mill webapp. The client generates a random data encryption key; seals it with the password; and then submits the sealed version to be stored in the user's profile on the web server. The web server can't unseal the original data encryption key without the original password, and it never sees that, only the KDF(1) version of it. That's all they've really done here. There is one more level of key indirection for the blobs themselves that i think is irrelevant but maybe useful for key rotation. Totally agree that unpadded RSA and ECB suck as primitives - they were bad choices then, they are bad choices now, and AEAD is a no-brainer upgrade (EDIT: and would close the post-back oracle) - but aside from picking better primitives the mechanism really does seem okay to me. I'd love to hear more from you though,
- winterdeaf 4y ago> well-reviewed zero-footgun nacl.SecretBox()-style thing for this use case, but there simply isn't. You'd be surprised, but I've seen designers who managed to shoot themselves in the feet with SecretBox() calls alone. Anything more complex than using a library that does the crypto for you calls for an external/crypto team review.