views:

957

answers:

2

When passing symetrically encrypted data in a URL or possibly storing encrypted data in a cookie, is it resonable and/or nessassary and/or possible to also pass the Symetric Encryption IV (Salt) in the same URL? Is the idea of using Salt even valid in a stateless environment such as the web?

(I understand how salt works in a database given a list of names or accounts etc. but we can't save the salt given that we are passing data in a stateless environment.

Assuming a server side password that is used to encrypt data and then decrypt data, how can Salt be used? I guess a separate IV could be passed in the query string but is publicly exposing the salt ok?

Or can one generate a key and IV from the hash of a "password". Assuming the IV and Key come from non-overlapping areas of the hash, is this ok? (I realize that the salt / key will always be the same for a given password.)

EDIT: Typically using AES.

+3  A: 

It is encouraged to generate random IVs for each encryption routine, and they can be passed along safely with the cipher text.

Edit:

I should probably ask what type of information you're storing and why you're using a salt with AES encryption, since salts are typically used for hashing, not symmetric encryption. If the salt is publicly available, it defeats the purpose of having it.

What you really need to do is ensure the strength of your key, because if an attacker has the salt, IV, and cipher text, a brute-force attack can easily be done on weaker keys.

John Rasch
Maybe my mistake. Is a salt and IV the same? or is salt typically added to the begining of the data to be encrypted. A bit out of my element here.
Andrew Robinson
+2  A: 

You should not generate an initialization vector from the secret key. The initialization vector should be unpredictable for a given message; if you generated it from the key (or a password used to generate a key), the IV will always be the same, which defeats its purpose.

The IV doesn't need to be secret, however. It's quite common to send it with the ciphertext, unprotected. Incorporating the IV in the URL is a lot easier than trying to keep track of the IV for a given link in some server-side state.


Salt and IVs have distinct applications, but they do act in similar ways.

Cryptographic "salt" is used in password-based key derivation algorithms; storing a hashed password for authentication is a special case of this function. Salt causes the same password to yield different hashes, and thwarts "dictionary attacks", where a hacker has pre-computed hash values for common passwords, and built a "reverse-lookup" index so that they can quickly discover a password for a given hash. Like an IV, the salt used is not a secret.

An initialization vector is used with block ciphers like DES and AES in a feedback mode like CBC. Each block is combined with the next block when it is encrypted. For example, under CBC, the previous block cipher text is XOR-ed with the plain text of the current block before encryption. The IV is randomly generated to serve as a dummy initial block to bootstrap the process.

Because a different IV is (or should be, at least) chosen for each message, when the same message is encrypted with the same key, the resulting cipher text is different. In that sense, an IV is very similar to a salt. A cryptographic random generator is usually the easiest and most secure source for a salt or an IV, so they have that similarity too.


Cryptography is very easy to mess up. If you are not confident about what you are doing, you should consider the value of the information you are protecting, and budget accordingly to get the training or consultation you need.

erickson
Just to make sure, repeately passing the same encrypted value across a query string with a different IV each time is ok. The key is server side, stays the same but the encrypted value changes with every request. I am ok from a design point. Just want make sure it is oke from a security point. thanks
Andrew Robinson
Yes, the IV should be unique per message. You'll end up sending IV+ciphertext as the full value for the other end to decrypt. Also make sure you have some way to authenticate the ciphertext was not modified, as AES won't do that.
MichaelGG
So a full message might end up being: cipherText = Encrypt(plaintext, HASH(plaintext)) in "IV+ciphertext". That way you have the unique IV to ensure same plaintext gets different ciphertext each time, and a hash of the plaintext for the receiver to verify the ciphertext wasn't tampered.
MichaelGG
I've always read and been told it is better to do integrity checking on the ciphertext before even decrypting it. Also, to keep someone from generating their own hashes, a HMAC should be used to generate the hash. So you end up with, IV, Ciphertext, and Hash to send to the other side. Hash = HMAC( IV + Ciphertext ).
jkf