How to store iv used to create cipher in nodejs's createcipheriv, for future decryption?

3.8k Views Asked by At

I'm new to cryptography and I'm using nodejs to serve an app.

My app uses config files that I want to encrypt them before production, and when nodejs server needs these files (in production) it will decrypt them.

I'm using crypto.createCipheriv(algo, key, iv) to encrypt. The algo is: 'aes-256-ctr'. The key is created with a password:

const key=crypto.createHash('sha256').update(String(password)).digest('base64').substr(0,32)

The iv is generated with:

const iv = crypto.randomBytes(16)

So if I want to decrypt the file, I need the key and the iv. I store the password used to generate the key (hashed), and I match it against user given password, but how I store and retrieve the iv?

When I write the iv (using fs.writefile and the iv const) to file and try to read it, when I try to decrypt I see the error:

Error: Invalid key length

even though when I generate and use the iv in the server it encrypts/decrypts without any issue.

So my question is: how do I store the IV that I used in order to decrypt the files later? How do I use it later when trying to decrypt?

Is there a better way/practice to encrypt configuration files and decrypt them? I want to serve my app with encrypted/hashed personal data, such as configuration data, user/password etc.

Is my way a good one or am I in the wrong direction? I will appreciate is some encryption savvy user can help me...

Thanks

1

There are 1 best solutions below

4
gusto2 On

So my quetion is: How do I store the IV that I used in order to decrypt the files later? How do I use it later when trying to decrypt?

You may store the IV as part prepanded to the ciphertext. When decrypting, you shall read the iv and then decrypt the rest

examples:

base64(iv)+'.'+base64(encrypted_data)
base64(iv + encrypted_data)
...

Is there a better way/practice to encrypt configuration files and decrypt them?

There are a lot of questions / answers for this on SO. The issue with encrypted configuration files is that the application needs the decryption key at its hand. So once someone gets access to the server, he may access the decryption key as well. But at least you don't leave the configuration credentials in plain sight.

In theory - it is possible to use TPM to encrypt the encryption key itself, but I have no idea if you can use TPM in NodeJS and as well your app would be bound to a specific motherboard (often you don't want that).

I want to serve my app with encrypted/hashed personal data, such as configuration data,

To pass the data to an application, just use SSL. Do not complicate it with own custom encryption. Still you may want to encrypt data at rest (stored in files or in a database), that's where the encryption should take place.

user/password etc.

Do not ever store user passwords. Even encrypted. Proper way to authenticate users is salted slow hash. Event that's not optimal, but it's the best we have.