Is it worth encrypting a password hash? - encryption

I was wondering if it is common practice to encrypt a password hash, and/or the salt, does it necessarily make it more secure or just increase the time it'd take to "guess" the password?
Thanks!

It's not common practice to encrypt a salted hash. It may slightly increase security but realistically it's not worth it, since you'd have to manage the key in some way, complicating the whole process. Using a salted hash with a secure hashing algorithm will be fine.

Generally, you don't need to encrypt hash as long as you use good cryptographic hash function. As for salt, salting is done best before encrypting, ie. salt does get encrypted. The exception would be one-time table, in which case you can easily salt afterwards. As for the third question, whole encryption is nothing but increasing the time it takes to "guess" the plaintext, exception being again one-time table. Now what's your concrete problem? Can you formulate it as a task in some concrete computer language?

If the hash was produced by a "good" algorithm, than it doesn't make any sense to cipher it, since you would be essentially ciphering something that in theory only the rightful user can generate.
Ciphering the salt doesn't add any kind of real security.

Related

Is it ok to store password as pbkdf2 hash in database?

I need to store password in Database. I m on windows and the only algorithm given by that platform is pbkdf2 (as far as I know). So is it OK so store my password as hash of pbkdf2? Or is their a better algorithm available via Windows API (Cryptography API or similar api available on Windows?). I also learn that PBKDF2+SHA512 is not so different than BCrypt
PBKDF2 is indeed a password hash and therefore designed for this kind of operation. That doesn't mean it doesn't have any drawbacks. As usual it has a salt and work factor (a more generic term than iteration count that PBKDF2 uses).
However it doesn't provide any memory hardness, so it is easier to create specialized hardware to attack it. Furthermore, a smart implementation can speedup the HMAC algorithm that is used for the designated hash function by performing pre-calculation. And finally it is super inefficient if you ask more bits than the output of the hash function - but that's not really a topic if you just use it as a password hash instead of (multi-)key derivation.
So PBKDF2 is old, but it is still a million times better than the idiotic amounts of hash(pasword) or hash(salt | password) schemes out there without salt and/or work factor. Literally, because you'd at least use a 1000000 as iteration count.
Note that using a password hash still allows for weak passwords; you should always add additional measures where possible, e.g. password guess limitations, password strength indicators and whatnot. It is mainly useful to protect your users passwords in case the login DB gets stolen.

Hashing, encrypting or both

Recently I have been looking to add some security to a project. I have been doing lots of research into the situation and discovered that clearly password hashing is a must. Further I have concluded that the best options are to use bcrypt, PBKDF2 or scrypt.
Also I have seen much discussion over hashing vs encryption and discovered that it is clear that hashing is more important. That said, after many searches into the depths of Google I have yet to find any information on whether encrypting an already properly hashed password is of any benefit, serves to harm or is relatively neutral.
Is the CPU cost of doing both worth it? Are there any pitfalls?
Encrypting something leads to the need of decrypting, which in turn leads to the problem you already have: secure storage of a secret.
Assuming that you want to store passwords as hashes instead of plain text you are basically doing this:
hashpw := hash(salt + password)
You then store salt and hashpw in a file and use this data instead of the plain text passwords. (Note that the order of the concatenation of salt and password is crucial in many cases and that this is only a visualization of the process, nothing more; Use a tool to generate salted hashes).
A possible attacker then needs to guess the salt and the plain text password to check for a match with
the stored hashpw, which is as secure as the hash algorithm you're using (rate of collisions).
Encrypting something using some cipher has the benefit of being able to restore the plain text, which
the hashing way does not offer. It also requires the system which decrypt the cipher text to have the
key available. Say you encrypt a string foo with some key bar. To decrypt the resulting cipher text
brn you need the key bar again. This key needs secure storage on your system and if the key is exposed
to the attacker, all security is gone.
As a general rule of thumb I would say that hashing provides a good way of storing texts which are
checked against (e.g., passwords) as the security of that is determined by the collision rate of the
hashing algorithm. Encryption on the other hand, is the technique you're using to store the rest of
the data securely.
You're on the right track. Use a key derivation/password hashing function like the ones you've mentioned.
Do not use just a hash or salted hash. The main issue is that traditional hashing algorithms (MD5, SHA-*, etc.) are intended to be fast. That's not advantageous for password storage, and many implementations are breakable, even if you add a salt.
Encryption always introduces key management-related issues. It should be avoided for password storage.
The advantage of a KDF is the work factor. It's designed to be slow and computationally expensive, which is why they're idea for this situation. Scrypt is the most resilient of the options you're looking at since it requires a set amount of memory to execute. This kills the GPU attack vector. There are tradeoffs whichever way you go, but all of your choices are fine as long as you use appropriate work factors where they're configurable.
I would simply encrypt the password. Hashing is fast, but a little unsafe for passwords. When I use hashing for security purposes, it's usually for things like message signing e.g. message + hash(message+password) so that the message can be verified, but I'm no expert in the field. I don't see the point of doing both.

AES/Rijndael: search on encrypted data - static salt and IV

I want to do searching on encrypted data. Which means that there is the need to have the same ciphertext every time I encrypt the same plaintext. I.e. think of a list of encrypted names and I want to find all "Kevin"'s in it. I would now encrypt "Kevin" and search the database for the encrypted text. All hits will be "Kevin"'s — but still only the one who has the password knows.
Now my question: What about security if I use the same salt and IV (to get the effect described above) all the time? Is the encryption still secure? Or is there any other method to do searching on encrypted data?
If you want to do a deterministic encryption then you should use an encryption mode
that has been designed for deterministic encryption (and not modify an encryption mode designed for something else).
One possibility is the SIV encryption mode described in
RFC 5297.
(Of course, deterministic encryption has its drawbacks, but discussing this is not part of this question.)

Is AES-256 secure if parts of solution is known?

i was wondering whether AES-256, with a strong key, becomes less secure when some part of the solution is known. as an example scenario, the string i want to encrypt is "my secret password is: du420rfashud". the attacker who tries to get my password knows that the string starts with "my secret password is: ". is it possible to decrypt the rest of the string in this case? also my second question is, if the attacker knows the complete solution, can he derive the key from that?
thanks
The scenario that you describe is called a known plaintext attack (or even a chosen plaintext attack). Good cryptographic ciphers are not vulnerable against those attacks, and that includes the AES family of ciphers.
Basically, no matter how much information you have except the key, finding the key is no easier than brute-force trying.
(Practically, such attacks are quite easy to mount, since all sorts of encrypted communication contains predictable standard headers. Therefore, such a vulnerability would make a cipher essentially entirely useless.)

Encryption: How to turn an 8 character string into a 128-bit key, 256-bit key, etc?

I tried to research this, but there were still some questions left unanswered. I was looking into figuring out how an 8 character password gets turned into a high-bit encryption key. During my research I found articles that would talk about the salt value.
Assume you could get all 256 characters to play with, then an 8-character password would be 64-bits long. So, the remaining 64 bits is simply a salt value. And, correct me if I'm wrong, but this is done so that if someone was going to try to try ALL the possible values (brute force) they'd have to try all 128-bits since even the salt is unknown.
My questions really relate to this 'salt' value:
When someone makes an application, is the salt value hard-coded into it? And if so, can't it be obtained through reverse engineering the executable?
If the salt is generated at random, then I assume it must have some way to duplicate it. So, isn't that function that returns a random salt able to be reverse engineered to force it to duplicate itself to get the salt value?
This might be out of the scope, but if a salt value is generated on a server side (of a client/server relation), then wouldn't it have to be shared with the client so they can decrypt data sent by the server? And, if it's being sent over to the client, can't it be intercepted which makes it useless?
Is there some other method that is used besides this 'salt' value that can turn an 8-character string into a strong encryption key?
As usual with security-related questions, this answer's going to be a long one.
First, the simple answer.
Q: How does one turn an 8-character string into a 128-bit key?
A: One doesn't.
This is a truthful answer. Now, one that's more appropriate to what you're asking:
A: Create a random 64-bit value, and store it with the password in the database. Now, the password is half the key, and the random value is the other half.
This one is a lie. Here's what you actually do:
A: Hash the password along with a random salt using a method producing 128-bit or longer output. Use 128 bits of that as the key. Store the salt.
Now to address your questions on salt. First off, the purpose of salt is not really to lengthen encryption keys. It is to prevent people building rainbow tables - mappings from hashed to unhashed forms. To see that your encryption is no stronger, just imagine the attacker knows your key-extending algorithm. Now, instead of guessing 128-bit keys, he just guesses your 64-bit password and then uses the same algorithm. Voila. If the salt is unknown to the attacker, yes, you've gained a bit, but they must already have your ciphertexts to attack them, and the salt must be stored in the plain along with the ciphertext. So this is an unlikely scenario.
Salt is random per encryption key.
Random means random. If you are insufficiently random when you use a cryptography algorithm which assumes unpredictable material, you are vulnerable. That's what /dev/random is for - the system entropy pool is very good. Get a better hardware RNG if you're worried.
Yes, if you salted the key, someone needs the salt to decrypt things you encrypted using the salted key's hashed value. No, sending the salt does not necessarily compromise your data; send the salt only to someone who has proved they already have the password, but it's stored in your database next to the ciphertext. As mentioned above, someone needs both the salt and the ciphertext to mount an attack. Again, the purpose of the salt is not to raise the strength of the encryption, it is only to prevent precomputation attacks against your hashes.
There are methods of key extension. But, fundamentally, your protection is only so strong as its weakest link, so to provide 100% unbreakable encryption you will need a one-time-pad (a truly random key as long as the data to be encrypted). In the real world, what is usually done is hashing the password along with a salt to produce unpredictable longer keying material.
The function that turns a password or passphrase into a cryptographic key is called a Key Derivation Function (this might help you searching for more information on the topic). Such functions take a password and a randomly generated salt, and produce a key through a process that is deliberately computationally intensive. To reproduce that key, you must have both the password and the salt - so you are correct, the salt must be stored or transmitted along with the encrypted data.
The reason that Key Derivation Functions use a salt is to increase the work factor for any attacker. If a salt was not used, then a given password will only ever produce one single key. This means that an attacker can easily create a dictionary of keys - one key for each word in his dictionary. If, on the other hand, a 64 bit salt is used then each password can produce ~2**64 different possible keys, which expands the size of the dictionary by the same factor. This essentially makes producing such a dictionary ahead-of-time impossible. Instead, the attacker has to wait until he's seen the salt value, and then start generating keys to test. Since the key derivation function is computationally expensive, this is slow, and he won't be able to get far through his dictionary in a reasonable timeframe.
1) Each password is salted differently, and the salt is stored with the hash.
2) It's stored.
3) No, the client never decrypts anything. It sends the password, which the server salts, hashes and compares.
4) Yes, I'll add a few links.
Salts are generally not hardcoded, but they are generated at random, usually server-side, and never communicated to the user.
The salt would be stored in a database, separate from the passwords. The idea is that even if the password hash database is stolen, it would be very difficult to get the actual passwords (you'd have to try a lot of combinations), without having the salts as well. The salts would be generated at random, and different for each user, so even if you found it out for one, you'd still need to find all the others.
The salt is never sent, because the client never decrypts anything. The client sends the password to the server, the server adds the salt (which is randomly generated and stored for each user, and the user never know it).
So basically on this is what happens.
On registration:
User sends password to server.
Server adds a random salt to the password and then hashes it.
The salt and final hash are stored in separate tables.
On login:
User sends password to server.
Server fetches stored hash, and adds it to the password.
Server hashes the password and salt.
If the final hash matches the one in database, the user is logged
in.
...Is there some other method that is used besides this 'salt' value that can turn an 8-character string into a strong encryption key?
YES but...
You can compute the hash of that 8-character string:
For example if you need a 256 bit key:
key-256bit = hash(8-character string) //use SHA-256 - very secure
key-128bit = hash(8-character string) //use MD5 no more considered secure
"into a strong encryption key?" about strong.... depend how strong you need it because if you use only a 8-character string it mean that you could only create 2^8=256 different hash values and that's an easy task to brute force!!
conclusion: a salt would be of great value!
cheers
Daniel

Resources