1

I am attempting to write a function to encrypt and decrypt data using NodeJs following current best practices.

In order to achieve this I am doing the following:

  • Taking an end user password and enforcing password strength requirements
  • Generating 128 random bytes for a salt
  • Hashing the user password with pbkdf2 and the salt
  • Generating 16 random bytes for an IV
  • Encrypting my data with AES-256-CBC using the IV, and hashed password
  • Storing the encrypted data as a string in the format iv:salt:encryptedData

I'm assuming that using something like Argon2 for the hashed password would be superior, although everything I have read so far about encrypting files recommends pbkdf2.

Is it safe to store the salt and IV in the encrypted file? I'd like to only require a password for decrypting the file, so this would be preferable. I am under the impression that this protects me against a rainbow table style attack. I am not certain if this significantly increases the likelihood of someone being able to decrypt the data.

Is there anything else I could be doing to improve the security of the encrypted file?

This gist contains my exact code: https://gist.github.com/briancw/485e2645f7da16eaa3b530dd913297a5

6
  • The salt and IV only need to be unique, they don't need to be secret. You can even have the IV generated from the key, eliminating the necessity to store it. As the salt already ensures the resulting key will be unique, there is no risk of IV re-use. I would however recommend you use an existing library/function to do encryption, though, rather than trying to implement it on your own.
    – forest
    Dec 20, 2017 at 2:34
  • Thanks @forest. I attempted to find a more vetted solution but couldn't find anything that appeared to be sufficient. I looked through the source code of any npm modules I could find that looked production ready. Any that I looked at appeared to have flaws. I believe the next best method then is to use some sort of existing binary and write/find some bindings for it, although this seems not much better than what I've done here. Any resources I've been able to find on doing encryption with Node suggested using Crypto directly.If you could suggest an existing library I would love to look at it. Dec 20, 2017 at 4:19
  • Try libsodium/NaCl. It seems there are several ports of it to Node, e.g. github.com/jedisct1/libsodium.
    – forest
    Dec 20, 2017 at 4:30
  • 1
    @forest Thank you very much. I'll almost certainly be using one of those ports in my project. Dec 20, 2017 at 4:49
  • 1
    I've just realized that another post where I got a recommended salt size was in fact recommending 128 bit salts, not 128 byte. Dec 20, 2017 at 7:34

1 Answer 1

1

A popular crypto library is libsodium, based on NaCl, which provides an easy way to perform basic cryptographic operations like key exchange. It supports few algorithms, but the ones it does support are modern, secure, and chosen to work in a wide-variety of situations, removing the necessity to be understand the details of various crypto primitives. The library is for C, but it has been ported (usually in the form of C bindings) to many different languages, including to Node.js.

Installing it for Node.js is simple:

npm install libsodium

Not the answer you're looking for? Browse other questions tagged .