What is the correct (acceptable) way to derive an, lets say 128 bit AES key from the secret derived in a DH negotiation?
Use the first 128 bit
Hash the secret and use the first 128 bit
Use some more complicated derivation function
How would you derive a set of keys in a "correct" manner?
I would use a standard. One such standard is NIST Special Pub 800-56A. See in particular section 5.8.
For instance, in TLS used pseudo-random function, which is based on SHA1 and MD5 hash over shared secret (i.e. DH key exchange value), string label (to distinguish different cases for which key is generated, HMAC, cipher and so on), and shared random parameter (both client and server generates his own half of random parameter).
So, i'd recommend to add some random data generated by both client and server, and hash it together with DH key exchange value.
Related
Can we assume that same encryption key is used to encrypt data if encrypted data are same?
For example, plain text is 'This is sample'.
First time we use 3DES algorithm and encryption key to encrypt it. Encrypted data became 'MNBVCXZ'.
Second time again, we use 3DES algorithm and encryption key to encrypt it. Encrypted data became 'MNBVCXZ'.
My questions are:
Can I assume static encryption key is used in this encryption process?
How many keys can be used to encrypt data using 3DES algorithm?
Can I assume static encryption key is used in this encryption process?
Yes, if you perform the encryption yourself (with a very high probability), no if an adversary can perform the encryption and the plaintext/ciphertext is relatively small.
As 3DES does indeed have 2^168 possible keys and 2^64 possible blocks, it should be obvious that some keys will encrypt a single plaintext to the same ciphertext. Finding such a pair of keys requires about 2^32 calculations on average (because of the birthday paradox).
If the plaintext is larger (requires more than one block encrypt) then the chance of finding a different key that produces the same ciphertext quickly will go to zero.
If one of the keys is preset it will take about 2^64 calculations to find another key. And - for the same reason - there is only a chance of 1 / 2^64 to use two keys that unfortunately produce the same ciphertext for a specific plaintext.
If you want to make the calculations yourself, more information here on the crypto site.
How many keys can be used to encrypt data using 3DES algorithm?
2^168 if you consider the full set of possible keys, i.e. you allow DES-ABC keys. These keys are encoded as 192 bits including parity. This would include DES-ABA and DES-AAA keys (the latter is equivalent to single DES).
2^112 if you consider only DES-ABA keys. These keys are encoded as 128 bits including parity. This would include single DES.
is it possible to retrieve AES key using AES initalization vector and encrypted data?
I have AES initalization vector and encrypted data. I have seen a online tool for decrypting AES encrypt data using AES key and AES initalization vector.
online tool: http://aes.online-domain-tools.com
When i entered any key in AES key field, it is showing AES initalization vector in initialization field.
So, I have question that if i have AES initalization vector then is it possible to retrieve AES key?
No, the AES key cannot be retrieved from the initialization if AES was applied correctly. In that case the IV and AES key should be independent of each other.
Sometimes the AES key and IV are however generated by hashing over some common value. This is not a secure method of creating an IV. In that case the IV can possibly be used as distinguisher to validate if a particular key is correct (but in general such a test can also be performed over the ciphertext. Deriving the IV from the key makes the use of an IV moot in the first place, IV's should be used to make a cipher secure when a key is reused!
Sometimes the AES key is not generated correctly, for instance by using MD5 over weak password, or by directly applying a password as a key (after padding it to the required size). In that case you may use a dictionary (and related) attacks, basically brute forcing the password to get the key. It is easier to test the correctness of the result if the IV is directly derived from the key .
Both above techniques seem to be used by the above online tool. It clearly shows you how not to apply AES.. Don't trust shit websites that are popular because they just choose an interesting name.
I know KDF (Key derivation function) are used to stretch user passwords, which are basically not suitable to be used as keys in cryptographic algorithms.
But what if I create a random key (random 32 bytes), do I still need to use KDF on it to ensure proper encryption?
A KDF is typically used for deriving cryptographic keys from things like passphrases, which as you correctly say are not suitable for direct use. But they are also used for deriving additional keys from a master key, which depending on your overall scheme, might be useful.
Suppose you used a key agreement protocol where both parties ended up with a random shared secret. You could use a KDF to derive a key for encryption, and one for message integrity (for example, an HMAC key).
From NIST SP800-108:
When parties share a secret symmetric key (e.g., upon a successful
execution of a key- establishment scheme as specified in 1 and
[2]), it is often the case that additional keys will be needed (e.g.
as described in [3]). Separate keys may be needed for different
cryptographic purposes – for example, one key may be required for an
encryption algorithm, while another key is intended for use by an
integrity protection algorithm, such as a message authentication
code. At other times, the distinct keys required by multiple entities
may be generated by a trusted party from a single master key. Key
derivation functions are used to derive such keys.
The short answer is, no, you don't need to use a KDF, assuming your key generation is correct.
I am creating an encryption scheme with AES in cbc mode with a 256-bit key. Before I learned about CBC mode and initial values, I was planning on creating a 32-bit salt for each act of encryption and storing the salt. The password/entered key would then be padded with this salt up to 32 bits.
ie. if the pass/key entered was "tree," instead of padding it with 28 0s, it would be padded with the first 28 chars of this salt.
However, this was before I learned of the iv, also called a salt in some places. The question for me has now arisen as to whether or not this earlier method of salting has become redundant in principle with the IV. This would be to assume that the salt and the iv would be stored with the cipher text and so a theoretical brute force attack would not be deterred any.
Storing this key and using it rather than 0s is a step that involves some effort, so it is worth asking I think whether or not it is a practically useless measure. It is not as though there could be made, with current knowledge, any brute-force decryption tables for AES, and even a 16 bit salt pains the creation of md5 tables.
Thanks,
Elijah
It's good that you know CBC, as it is certainly better than using ECB mode encryption (although even better modes such as the authenticated modes GCM and EAX exist as well).
I think there are several things that you should know about, so I'll explain them here.
Keys and passwords are not the same. Normally you create a key used for symmetric encryption out of a password using a key derivation function. The most common one discussed here is PBKDF2 (password based key derivation function #2), which is used for PBE (password based encryption). This is defined in the latest, open PKCS#5 standard by RSA labs. Before entering the password need to check if the password is correctly translated into bytes (character encoding).
The salt is used as another input of the key derivation function. It is used to prevent brute force attacks using "rainbow tables" where keys are pre-computed for specific passwords. Because of the salt, the attacker cannot use pre-computed values, as he cannot generate one for each salt. The salt should normally be 8 bytes (64 bits) or longer; using a 128 bit salt would give you optimum security. The salt also ensures that identical passwords (of different users) do not derive the same key.
The output of the key derivation function is a secret of dkLen bytes, where dkLen is the length of the key to generate, in bytes. As an AES key does not contain anything other than these bytes, the AES key will be identical to the generated secret. dkLen should be 16, 24 or 32 bytes for the key lengths of AES: 128, 192 or 256 bits.
OK, so now you finally have an AES key to use. However, if you simply encrypt each plain text block with this key, you will get identical result if the plain text blocks are identical. CBC mode gets around this by XOR'ing the next plain text block with the last encrypted block before doing the encryption. That last encrypted block is the "vector". This does not work for the first block, because there is no last encrypted block. This is why you need to specify the first vector: the "initialization vector" or IV.
The block size of AES is 16 bytes independent of the key size. So the vectors, including the initialization vector, need to be 16 bytes as well. Now, if you only use the key to encrypt e.g. a single file, then the IV could simply contain 16 bytes with the value 00h.
This does not work for multiple files, because if the files contain the same text, you will be able to detect that the first part of the encrypted file is identical. This is why you need to specify a different IV for each encryption you perform with the key. It does not matter what it contains, as long as it is unique, 16 bytes and known to the application performing the decryption.
[EDIT 6 years later] The above part is not entirely correct: for CBC the IV needs to be unpredictable to an attacker, it doesn't just need to be unique. So for instance a counter cannot be used.
Now there is one trick that might allow you to use all zero's for the IV all the time: for each plain text you encrypt using AES-CBC, you could calculate a key using the same password but a different salt. In that case, you will only use the resulting key for a single piece of information. This might be a good idea if you cannot provide an IV for a library implementing password based encryption.
[EDIT] Another commonly used trick is to use additional output of PBKDF2 to derive the IV. This way the official recommendation that the IV for CBC should not be predicted by an adversary is fulfilled. You should however make sure that you do not ask for more output of the PBKDF2 function than that the underlying hash function can deliver. PBKDF2 has weaknesses that would enable an adversary to gain an advantage in such a situation. So do not ask for more than 256 bits if SHA-256 is used as hash function for PBKDF2. Note that SHA-1 is the common default for PBKDF2 so that only allows for a single 128 bit AES key.
IV's and salts are completely separate terms, although often confused. In your question, you also confuse bits and bytes, key size and block size and rainbow tables with MD5 tables (nobody said crypto is easy). One thing is certain: in cryptography it pays to be as secure as possible; redundant security is generally not a problem, unless you really (really) cannot afford the extra resources.
When you understand how this all works, I would seriously you to find a library that performs PBE encryption. You might just need to feed this the password, salt, plain data and - if separately configured- the IV.
[Edit] You should probably look for a library that uses Argon2 by now. PBKDF2 is still considered secure, but it does give unfair advantage to an attacker in some cases, letting the attacker perform fewer calculations than the regular user of the function. That's not a good property for a PBKDF / password hash.
If you are talking about AES-CBC then it is an Initialisation Vector (IV), not Salt. It is common practice to send the IV in clear as the first block of the encyphered message. The IV does not need to be kept secret. It should however be changed with every message - a constant IV means that effectively your first block is encrypted in ECB mode, which is not properly secure.
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.
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.
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.