how does salt works on crypt function in c? [duplicate] - c

This question already has answers here:
How does password salt help against a rainbow table attack?
(10 answers)
Closed 8 years ago.
I read the man crypt and didn't understand what the phrase below means: salt is a two-character string chosen from the set [a-zA-Z0-9./]. This string is used to perturb the algorithm in one of 4096 different ways.

The primary function of salts is to defend against dictionary attacks versus a list of password hashes and against pre-computed rainbow table attacks.
Salt (cryptography)
Basically adding a little bit of unknown data into the hash prevents an attacker from precomputing all hashes for a given dictionary and then just looking up in the table to find the unhashed value.

Usually to encrypt sensitive data a salt is used.
What this means is your sensitive data (say password) is concatenated with a string(salt), encrypted and then stored.
This protects it against table attacks, in which an attacker, has most dictionary words and their popular algorithm encryption (md5, sha1, etc) Strings in a table. So if he were to have access to the db, he would be able to decipher all of your sensitive data.
Using a salt makes it harder for the attacker since - The attacker needs to know the algorithm used with which the salt was added and would need a specific dictionary for that specific salt, making his life harder.

Related

Converting encryption password from MD5 to SHA-256, does my protocol has a flaw?

I'm working on a website (PHP + MySQL) that I've got to upgrade. Passwords are stored in the database in MD5, and I'd like it to be something more secure, like SHA-256.
I've already red this question about "converting" password hashes, but I got an other idea, and I'd like to know if it brings a security problem or not.
Currently, the passwords are checked in php by hashing (in MD5) the given password and compare it with the hash stored in database, ie: if(md5($password) == $hash)
Let's assume that I hash all the MD5 hashes in SHA-256. I'd have the sha-256 hash of a md5 hash.
Side note: I know it's not more secure to rehash a hash, that's not the point of my question
When a user wants to connect, I'd just have to change the md5($pass) in hash('sha256', md5($password), false) to make it match the value stored in database (assuming $password is the right one)
It seemed a good idea to me as I don't need to keep track of the md5 hash after conversion, ad this doesn't need me to create any new column in my table. I know that this is not going to give me the SHA-256 hash of the original password stored with md5 hash, but this is not my goal. It's just to change the encryption method. Moreover, brute-forcing it seems inefficient, as it is very unlikely that dictionary would have hashes of words...
Does this way of doing it is flawed?
Simple hashing of passwords is insufficient, it is subject to rainbow tables and is to fast.
Instead in PHP use Safe Password Hashing: password_hash() and password_verify() or a comparable function such as PBKDF2, Bcrypt or script. These function are more secure because of two additions: a repetition count and a random salt. It's all about raising the work factor the attacker must perform.
After all, the point is to have a secure system. Just making it more inconvenient for an attacker is not the answer, there are hacking programs out there to take advantage of poor password security.

The point of hashing, and problems with it?

So from what I have seen it is impossible to decrypt any hashing algorithm such as MD5 or SHA-1 without brute forcing it or using rainbow tables. This seemed to confuse me on a few aspects of using hashes. These confusing points are:
What would be the point of hashing in the first place if they cant be decrypted?
How would hashed passwords be able to be used in a database?
Also since people say it is like the modulo operation, what, if anything, is preventing multiple inputs to equate to the same hash?
If somebody simply does SHA1 or MD5 on a password, then they get almost no protection.
That's why it's important to understand the right way to handle "password hashing". Please read Our password hashing has no clothes
To answer your questions:
You can verify the user without "decrypting the hash": you simply "hash" the user entered password (along with salt and other parameters) upon login and verify that it matches the expected result that is stored in the database.
See 1 and the Troy Hunt link
People who say it is like a modulo operation are making a bad analogy: they are non-experts on this subject. Anyway, the properties of the "hash" function make it hard to find collisions, and the salt prevents two users with the same password from having the same password "hashes" in the database.
Other resources:
Salted password hashing - Doing it right
Method to Protect Passwords in Databases for Web Applications -- advanced reading: solves other problems with current solutions to protecting passwords. If you wonder why I put "hash" in quotes above, this will explain it.
It's not like a modulo. A hash is reasonably guaranteed to be unique based on the input. If you enter your passwords in a database as hashes, then all you need to do is to hash the password entry and check it against what you have stored in the database. This way, you are not storing readable passwords in the database which are openly visible to others. Normally, you would have a private key, some salt and something unique like a timestamp included in your hashing algorithm to ensure that it cannot be easily spoofed.
This may help you further:
http://searchsqlserver.techtarget.com/definition/hashing
Even if the process of hashing is basically non decryptable, the problem as pointed before is that each hash is nearly unique, so that means using websites like md5decrypt which contains a lot of different words and their encrypted hashes, one may find the password he is looking for.
That is if the password isn't strong enough in the first place. Obviously one shouldn't use the password "password" for instance because it will probably be found in most of the websites like md5decrypt.
What you should do to protect passwords on your website is actually simple. First, don't use old hashes like md5 or sha1. Use at least sha256, and if you've enough sql storage, sha384 or sha512. You should know that most of the online hashes database are only about the most commonly used hashes (let's say md5,sha1,sha256 in most cases). So you should find a hash type that isn't very represented on online database.
Then you should (you have actually to) use salt when encrypt users passwords, that is add some word, letters, whatever, to the password before you encrypt it, then store that salt somewhere so you can still allow people to log in. You could also add a pepper to the salt to make the all thing stronger.
While using the salt, try to find a way that hackers won't think about, for instance double the salt, or triple it, or try different ways to concat the salt and the actual password, etc. You could also make a double encryption with double salt, like sha512(sha384()), which would be almost impossible to find.
But, please, do not store unencrypted passwords !

Does knowledge about value length compromise hash integrity

If I am storing a hashed value in a database, but the length of the original value being hashed is fixed (eg. always 4 characters), does this compromise the one-way nature of the hashing function?
More precisely, I have sensitive strings which I then encrypt and store in a database. In order to search for these strings, I don't want to decrypt every entry in the database, so I also store the hash of the first 4 characters of the string in another column. When I want to search the database I generate the hash of the first 4 characters of the search term and compare it to the stored hashes to find which entries match or could match and then decrypt those entries to check for collisions and get the rest of the data related to that entry.
My worry is that since an attacker would know that the length of the strings being hashed is constant (4 characters), he/she would only need to generate a table of all possible 4 letter strings and their hashes and look-up the hashed values stored in my database (thereby giving away the first 4 characters of the original sensitive string).
You're pretty much right in your conclusion. If an attacker knows that your hash is of a 4 character string, it's pretty trivial to find the plain text via brute force. In addition to giving the attacker knowledge of first 4 characters of your sensitive data, it could also allow them to gain knowledge of part of the key you are using to encrypt your data (on a simple level encryption is key XOR plaintext, that means plaintext XOR encrypted = key). While it would be challenging to use that information to break the rest of the encryption, cryptographic attacks have been build on less.
Depending on the type of search you want to perform there are a couple options you may use to improve upon your scheme:
Search for full strings: You could encrypt the search term and query on that. Or store the hash of the encrypted string, and query on that if your strings are very long.
Search for partial strings: Alter your scheme by using a keyed hash instead of a simple hash.

Encrypting a file from a password using libgcrypt

I'm developing simple software that does aes256-cbc encryption of a file. I'm using GNU/Linux and libgcrypt-1.5.0. The IV is randomly generated with the OpenSSL rand function and the IV is stored before the ciphertext in the output file. I'm using the PKCS#7 padding method.
Now I am in doubt about how to proceed:
It is better to use sha256 repeated 50,000 times of the inputed password to encrypt the file, or it is better to use the password given by the user?
If I want to check the correctness of the inputed password, I have to store it into the encrypted file (obviously encrypted). Is it correct to do this?
Use PBKDF2 to derive a key as indiv suggested.
Use PBKDF2 with a different salt to derive an authentication key and append a MAC to your encrypted data (after encryption is more secure than before encryption). Verify the MAC in order to check whether the password is correct or not, and that the data has not been tampered with. If you are unsure when choosing a MAC, use HMAC with SHA-512 (assuming you are using AES-256 as per your question).
Instead of using PBKDF2 twice with different paddings, you can use a single invocation of PBKDF2 to generate both the encryption and the authentication keys at the same time, by generating a key of the combined size of your encryption key and authentication key in one go.
Note that depending on the padding for deciding whether the key was good can result in CBC padding oracle attacks. For file encryption such attacks might not be applicable, depending on the exact circumstances, but it seems prudent practice to use a proper MAC for data authentication anyway, since you also want to prevent bit flipping attacks and other malicious modifications to your data.
Neither choice is correct. You need to use an algorithm made for deriving a key from a password, like PBKDF2. See the function gcry_kdf_derive.
1.It is better to use sha256 repeated 50,000 times of the inputed password to encrypt the file, or it is better to use the password given by the user?
You never use the "raw" password directly as a key. The key needs to be strectched in something hardened against brute forcing attacks. Look at the String-to-Key (S2K) stuff, or a Password Based Key Derivation Function (PBKDF) with a memory-hard hash like scrypt.
2.If I want to check the correctness of the inputed password, I have to store it into the encrypted file (obviously encrypted). Is it correct to do this?
No. You use an authenticated encryption mode like GCM. Authenticated encryption modes are specially built for the task and provide both confidentiality and authenticity.
Under the password, the encrypted file will verify or it won't. Don't concern yourself with the reason why. Otherwise, you're setting up an oracle which may undo everything from Step 1 (which may or may not be applicable here).

Using a hash of what you are hashing as a salt?

Say a user registers for your site, you hash the password they have chosen then use that hash as a salt and rehash their password with that salt.
Example:
String hash1 = MD5(password);
String endHash = MD5(hash1 + password);
then store endHash in your database. Would this effective agaisnt Rainbow Table attacks if my database was comprimized? Or am i missing something that would make it easy to break?
This is key strengthening (http://en.wikipedia.org/wiki/Key_strengthening), a nice technique that nonetheless does not substitute for actual salt. It will not protect you against a rainbow table written with this double-hash function.
The point of salting is to prevent the use of huge precalculated tables. With this method it is possible to calculate the hash of any password without the need to access your database. You should store a random value and hash the password and that value together.
The weakness of hashed passwords is the attacker's knowledge of your hash function. If they know your hash function but not your salt, the salt has protected your passwords. If they know both the hash function and your salt, your data is at risk.
As this applies to your question - using dynamic salt generally makes it more difficult to figure out your salt. This increases security, but won't help if someone knows your algorithm.
Increasing your complexity in this way does make your system harder to crack. Nothing is uncrackable given enough resources, however.
Instead of hashing two times you should use the username as salt for the function:
String hash = MD5(username + password)
You should also consider using a different function as md5 is considered broken MD5
Doesn't make a difference: Your stored data is still based exclusively on the password, so there's no additional protection.
Also, you should avoid MD5 in favor of a currently-strong hash algorithm, such as SHA1, SHA-256, SHA-512.

Resources