Let me start by saying that I am new to the encryption arena. With that said, I am developing an application and need to store username, password and full name (first, middle, last) encrypted in a database table. I was reading an article that the IV should be random for each encryption that occurs and that I could prepend the IV to the ciphertext.
This is where it gets confusing. How would I decrypt the string if I prepend text to it unless I know exactly where in the string the IV ends and the ciphertext begins? Also, I was reading that I should salt the string by appending or prepending additional text before I actually encrypt. I.E., some string I create and prepend or append that to the plaintext, am I correct in my understanding of salting?
If I am storing the encrypted username and password in the database, should I worry about any issues when I need to authenticate a user. Can I reliably encrypt the username and password after the user enters the fields, then compare the encrypted values against the encrypted columns in the database? It seems as if this would be a problem and if so, what is the recommended way of handling this?
The length depends on the encryption algorithm that is used. AES's IV is always 16 bytes long, so in the decryption, you can just take the first 16 characters as the IV, then start decrypting after the 16th byte.
Yes, IV is like salt, just that salt is usually referred when we are doing hashing, instead of encryption. Salt is also of a fixed length.
If you only need to authenticate user, hashing is preferred way of storing the password in the database.
Related
I have an AES-encrypted string ( out of a user backup of a discontinued App) that I want to decrypt.
What I have:
json file with:
Info that key was created with PBKDF2
salt
encrypted string
I do know the password, with which the backup was created, probably the password also for PBKDF2
Is there a way to find out with what parameters the string was encrypted? i.e, how the key was created
Is there an easy way to decrypt the string?
Fortunately, reverse engineering the encryption method and the way that the ciphertext (and possibly other information necessary for decryption) is stored in the file, is a lot easier than trying to crack the password that was used to derive the encryption key. Being that you know the password that the key was derived from, there may be hope.
Is the encrypted string from the json file encoded using an encoding method that you recognize, such as hexadecimal or base64? If so, then when you decode the encrypted string, is it exactly 128 bits?
If so, then the problem gets significantly simpler, because this means that it's only one block of AES encryption. This means that you don't have to worry about the encryption mode (e.g. CBC, GCM, ECB, CTR, etc), or the IV if it's a block cipher mode such as CBC.
In addition, if there is information in the json file about the inputs to the PBKDF2 function (e.g. number of iterations, and/or hash algorithm), this can be helpful.
In the end, it comes down to trial and error, where different values for the parameters that you don't know are tried, until the correct parameters to the PBKDF2 function are found, which produces the correct key, to decrypt the cipher text. This also requires that you know something about the plaintext, in order to know when the decryption was successful.
Of course, the more parameters that unknown, the more rounds of trial-and-error are necessary. If the number of rounds of trial and error are reasonable given an allotted amount of time and resources, then the process can be automated in a fashion similar to https://security.stackexchange.com/questions/226935/write-a-python-or-c-program-to-guess-the-key/226950#226950.
I am new in cryptography. I need to encrypt a text using AES with some configuration
Encryption mode: GCM
Key size: 256 bits
Nonce size: 96 bits
MAC size: 128 bits
As AES is a symmetric algo. so i have a secrete key. I googled and found
nonce is a random number used to make sure a message is unique
But i have a doubt, how i can perform decryption, if nonce is a random number. do i need to store nonce along with each encryption. or any other way i need to split nonce, cipher and mac using key.
how can i use the provided configuration for encryption.
But i have a doubt, how i can perform decryption, if nonce is a random number. do i need to store nonce along with each encryption.
Yes, result of the encryption stored/sent is nonce, ciphertext, mac.
how i can perform decryption, if nonce is a random number
Nonce is randomly generated when encrypting the input and the nonce is then passed along the ciphertext (very often the nonce is prepended as the first block). Indeed you need THE SAME nonce value when decrypting, then the nonce is part of the input for decrpytion, not random
or any other way i need to split nonce, cipher and mac using key. how can i use the provided configuration for encryption.
There is a standardized message format for encrypted document or encrypted XML messages, but these are pretty pretty complex.
In reality - for simpler applications very often we see the encryption output composed as IV || ciphertext || MAC (as concatenation). IV and MAC are having fixed length, so you can cut them out and use the parameters for decryption.
decryption is happening on different machine and language. they have shared only a key for encryption. same key they are using for decryption. if i will add any random value as nonce then how hey will know what logic i have used for nonc
It doesn't matter until you provide the same input. As already mentioned - you may pass the IV (nonce) as part of the message and before decryption separate the nonce and original ciphertext.
BTW: I have a few encryption examples linked
Precisely, the nonce must be stored with the cipher text.
Remember, the nonce being part of the cipher text doesn't give the attacker any advantage.
From Wikipedia:
An initialization vector has different security requirements than a key, so the IV usually does not need to be secret. However, in most cases, it is important that an initialization vector is never reused under the same key. For CBC and CFB, reusing an IV leaks some information about the first block of plaintext, and about any common prefix shared by the two messages.
The purpose of initialization vector is to insert some randomness the encryption process so that an attacker cannot know when two identical plaintext messages have been encrypted with the same key.
IV is required for decryption, you can simply send it concatenated with the ciphertext.
IV || ciphertext
The most common way to transmit an initialization vector is, indeed, to prepend it immediately before the ciphertext.
If I am using Rijndael CBC mode, I have no idea why we would need salt.
My understanding is even if people know the password, but he cannot get the data without IV.
So from my perspective, password + IV seem to be sufficent secure.
Do I get anything wrong?
Yes, you need all of these things.
Salt (and an "iteration count") is used to derive a key from the password. Refer to PKCS #5 for more information. The salt and iteration count used for key derivation do not have to be secret. The salt should be unpredictable, however, and is best chosen randomly.
CBC mode requires an initialization vector. This is a block of random data produced for each message by a cryptographic random number generator. It serves as the dummy initial block of ciphertext. Like the key-derivation salt, it doesn't have to be kept secret, and is usually transmitted along with the cipher text.
The password, and keys derived from it, must be kept secret. Even if an attacker has the parameters for key derivation and encryption, and the ciphertext, he can do nothing without the key.
Update:
Passwords aren't selected randomly; some passwords are much more likely than others. Therefore, rather than generating all possible passwords of a given length (exhaustive brute-force search), attackers maintain a list of passwords, ordered by decreasing probability.
Deriving an encryption key from a password is relatively slow (due to the iteration of the key derivation algorithm). Deriving keys for a few million passwords could take months. This would motivate an attacker to derive the keys from his most-likely-password list once, and store the results. With such a list, he can quickly try to decrypt with each key in his list, rather than spending months of compute time to derive keys again.
However, each bit of salt doubles the space required to store the derived key, and the time it takes to derive keys for each of his likely passwords. A few bytes of salt, and it quickly becomes infeasible to create and store such a list.
Salt is necessary to prevent pre-computation attacks.
An IV (or nonce with counter modes) makes the same plain text produce different cipher texts. The prevents an attacker from exploiting patterns in the plain text to garner information from a set of encrypted messages.
An initialization vector is necessary to hide patterns in messages.
One serves to enhance the security of the key, the other enhances the security of each message encrypted with that key. Both are necessary together.
First things first: Rijndael does not have a "password" in CBC mode. Rijndael in CBC mode takes a buffer to encrypt or decrypt, a key, and an IV.
A "salt" is typically used for encrypting passwords. The salt is added to the password that is encrypted and stored with the encrypted value. This prevents someone from building a dictionary of how all passwords encrypt---you need to build a dictionary of how all passwords encrypt for all salts. That was actually possible with the old Unix password encryption algorithm, which only used a 12-bit salt. (It increased the work factor by 4096). With a 128-bit salt it is not possible.
Someone can still do a brute-force attack on a specific password, of course, provided that they can retrieve the encrypted password.
However, you have an IV, which does pretty much the same thing that a Salt does. You don't need both. Or, rather, the IV is your salt.
BTW, these days we call "Rijndael" AES.
A salt is generally used when using a hash algorithm. Rijndael is not a hash, but a two-way encryption algorithm. Ergo, a salt is not necessarily needed for encrypting the data. That being said, a salted hash of a password may be used as the Key for encrypting data. For what you're looking for, you might wish to look at hybrid cryptosystems.
The Key should be considered private and not transmitted with your encrypted data while the IV may be transmitted with the encrypted data.
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.