Hey Rustaceans! Got an easy question? Ask here (39/2021)!

Any recommendations on encryption libraries?

There's not really an easy answer here. If you think about it, it's kind of silly to expect one considering this is the kind of question that many people have based their whole careers around. I am not an expert, I'm just sharing what little I know. Please check back for any corrections in the replies.

In general, what you're looking for some kind of authenticated encryption scheme, which will both protect the passwords and ensure that they haven't been tampered with. AEAD is probably overkill for this application, although you could set the user ID or ID of the sub-account or something like that as the Additional Authenticated Data to prevent an attacker from swapping passwords around in the database (not sure what they could get out of that besides just breaking people's ability to login, but you never know).

Some people might say "use sodiumoxide, the C library it's based on has been well audited and the API is designed to be easy to use."

That's probably a decent choice, but watch out for pitfalls. You need a C compiler available to build the underlying libsodium. You need to make sure that you call sodiumoxide::init() at the start of your program, and you need to make sure you don't reuse nonces (although it gives you gen_nonce() for that). You need to generate a new nonce for each encrypted password and store that alongside it in plaintext.

One thing though, how are you planning to generate the key for encrypting the passwords? You're authenticating with a third-party service, so asking the user for a master password is probably out (although I would suggest that you reconsider that).

Does the third-party service return a token for the user? You could shove that through sodiumoxide::crypto::pwhash, though keep in mind you'll need to store the salt from pwhash::gen_salt() somewhere.

Also consider the structure of the token and if it's possible to forge; if it's relatively low entropy then it's probably worse than a user-chosen password. If it's a JWT from, say, Sign in with Google/Apple, then be sure to keep the signature section as that's the only part that can't be forged. If you're storing it in plaintext to access APIs on behalf of the user, then it's basically useless as an encryption key as an attacker with access to the encrypted passwords will have access to the token as well.

If you'd prefer pure Rust, the RustCrypto org has some options.

For key derivation, you could use the argon2 crate (the API is designed around password hashing but the principles are the same; the derived key would be in PasswordHash::output). However, while the Argon2 algorithm is considered state-of-the-art, note that the argon2 crate doesn't appear to have received a formal audit yet.

Then for authenticated encryption, you could use the aes-gcm crate from the same org, which has been audited.

Regardless of how you implement this, given the potentially sensitive nature of your application, I would highly recommend at the very least bringing in a security consultant from a reputable firm for an audit before you go live.

/r/rust Thread Parent