PasswordDeriveBytes function - c#

I am using AES (Rijndael) symmetric-key algorithm to encrypt-decrypt data.
I am using the System.Security.Cryptography. PasswordDeriveBytes function;
PasswordDeriveBytes password = new PasswordDeriveBytes(
passPhrase,
saltValueBytes,
hashAlgorithm,
passwordIterations);
Looking this function up on MSDN etc, it does not tell you explicitly what parameters ‘hashAlgoritm’ can take.
There are examples on the internet of it taking SHA1 as well as SHA256. I experimented with this and found that it can take SHA512.
But without documentation, I have no idea if SHA512 is really better than SHA256 or SHA1 or even MD5.
Can anybody shed light on this issue?

The security of the hash method is slightly less important for a key derivation function. It's probably best to choose one that matches the required key size, although use of MD5 in general should be discouraged. Other applications may only use SHA-1 .
Note that PasswordDeriveBytes has been deprecated and should certainly not be used for output larger than the hash size. Use PBKDF2 istead, see Rfc2898DeriveBytes.

Related

Rijndael algorithm alternative for password hashing

When I choose password encryption, I have found that Rijndael algorithm is one of the best encryption which cannot be cracked through brute force attack.
So I have choosen Rijndael algorithm for user's password encryption.
Now I have identified that, hashing (Irreversible) is more secure than encryption (Reversible) [Please correct me if I am wrong]
Here my question is,
Can I go with the existing implementation Rijndael algorithm
If I should not do encryption, Which one should be a best hashing algorithm.
I have referred the following website when implementing Rijndael algorithm.
http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndael(v=vs.110).aspx
How to generate Rijndael KEY and IV using a passphrase?
http://www.obviex.com/samples/encryption.aspx
OWASP lists some good practices for password storage.
You basically apply a protection_function to convert the credential to a protected form:
[protected form] = [salt] + protect([protection func], [salt] + [credential]);
You also add a salt so two versions of the same credential have a different stored form.
They also list the order in which you should choose hashing functions (yes, hashing is better than encrypting so that the password cannot be reverse engineered, even by the website owner). Argon2 and PBKDF are generally good choices for a protection_function.
Read the rest of the guide too. Also this related Security SE post about why AES (i.e. Rijndael) encrypted password storage is worse than even a not-so-strong hash (#Salvador's comment).
The problem with encryption is, that when an attacker get the key, he can decrypt all passwords of the database in no time, and therefore knows the original passwords which can be tried on other sites.
Since hashing is irreversible (there is no way to get back the original password), an attacker cannot use the hashes, even if he has control over the server. The same goes for the owner of the site.
Today recommended algorithms are BCrypt, PBKDF2 and SCrypt, all of them have a cost factor which controls the necessary time to calculate a single hash. The longer it needs, the more difficult it will be to brute-force.

Security of AES encryption with constant salt

I have an encoding application written in C# where users can optionally encrypt messages. I had been using the class in this answer, and it turns out I'm in good company because I found several places online that use the exact same code (one of which is Netflix's Open Source Platform).
However, comments to that answer (as well as later edits to that answer) led me to believe that this method was insecure. I opted to use the class in this answer to the same question instead.
How secure is AES encryption if you use a constant salt? How easily can this method be broken? I admit that I have very little experience in this area.
AES is a block cipher. A block cipher's input is a key and a block of plaintext. A block cipher is usually used in a block cipher mode of operation. All secure modes of operation use an Initialization Vector or IV. Otherwise identical plaintext would encrypt to identical ciphertext (for the same key), and this is leaking information.
Salt is not used by AES or modes of operation. It's usually used as input for Key Derivation Functions (KDFs), especially Password Based Key Derivation Functions (PBKDFs). Dot NET's Rfc2898DeriveBytes implements the PBKDF2 function as defined in - you'd guess it - RFC 2898: "PKCS #5: Password-Based Cryptography Specification Version 2.0".
If you use a static salt in a PBKDF2 then you would get the same key as output (for the same number of iterations). Now if you would ever leak the resulting key then all your ciphertext would be vulnerable. And if you would use multiple passwords then an attacker would be able to build a rainbow table; the PBKDF2 work factor would become less important; the attacker can simply build one table and then try all the resulting keys on all possible ciphertexts.
So, as the salt is not actually used for AES it doesn't make much of a difference for the security. It is however still a horrible sin, even worse than using the default iteration count for PBKDF2 / Rfc2898DeriveBytes.
Note that horrible security sins are committed by a large number of people on a daily basis. That there are many many many persons that get it wrong doesn't tell you that you are in "good company". That there are 289 upvotes just tells you that SO answers about cryptography should not be trusted based on vote count.
Salt is there for a reason.
This enables same input to be encrypted differently.
If an attacker would really insist, he can find some patterns that repeat themselves in encryption without salt, and eventually can get to your key more easily.
Still the attcker would have to work very hard.
Using constant salt equals to not using salt at all.
And it is highly recommended to use it, as it has no effect on the decryption process.

Rfc2898DeriveBytes with Sha2 in C#

I have a password hashing mechanism based upon Rfc2898DeriveBytes (based on code detailed here: http://crackstation.net/hashing-security.htm). Internally, this class utilizes SHA1 which - the CrackStation link does indicate the SHA1 is "old", but also states that, although Rfc2898DeriveBytes uses it internally, Rfc2898DeriveBytes is still a good mechanism.
The security department of a customer of mine has heard that that "SHA1 has been compromised" (specifically, that, for purposes of signing a document for transmission across the internet, SHA1 has been defeated, under certain circumstances - the fact that this "vulnerability" does not apply to a password hash is immaterial to the security department). As a result, they have demanded that we alter our password hashing mechanism to employ SHA2.
Currently, the .Net framework has no equivalent of Rfc2898DeriveBytes that employs SHA2 (or SHA256, etc.) internally. I know that I can use reflection to get at the source code for this class and change it, but I've always been told that the first rule of encryption is "don't grow your own".
This is principally a political demand by my customer, not a technical one, which could be easily satisfied by running the password through a SHA2 hash prior to running it through Rfc2898DeriveBytes. However, I am not sufficiently knowledgeable about cryptography to know if this might be bad - might in fact result in an objectively less secure password hash.
Does anyone know of an Rfc2898DeriveBytes equivalent class that employs SHA2? Or, does anyone know if running the password through a SHA2 hash prior to Rfc2898DeriveBytes would be perfectly safe?
Download the free code samples from "SecurityDriven.NET" book. Find the PBKDF2 class which takes an HMAC factory. Available factories include SHA2 (256, 384, 512).
Running the password through SHA2 hash prior to Rfc2898DeriveBytes is not the right thing to do, even if this is unlikely to be the weakest part of whatever you're doing (you'd be losing password entropy).

Rfc2898DeriveBytes and TripleDes

I have now learnt that PasswordDeriveBytes is deprecated in favor of Rfc2898DeriveBytes.
Looking up Rfc2898DeriveBytes on MSDN. There is a code example that uses TripleDES.
But TripleDes is older and weaker than AES. Why have they seemingly taken one step forward and one step back?
Can one just replace the TripleDes with AES or is Rfc2898DeriveBytes intrinsically linked to TripleDes?
A password based KDF simply turns a password+salt into a sequence of bytes which you can use as key, or store as password hash.
It's in no way linked to your choice of cipher, you can use PBKDF2 together with AES. One minor issue is how much data you read from PBKDF2-HMAC-SHA-1. I recommend only reading 20 bytes, and using a separate hash to increase their size when that's needed.
There is no reason to follow MSDN examples. They often do not follow good coding practices. Just because they use 3DES doesn't mean you should.
PBKDF2 (Rfc2898DeriveBytes) is used to derive a key from a password (Key Derivation Function), the key length it generates and what you do subsequently are your choice, so use PBKDF2 to generate they key and use which ever symmetric cipher you like. To answer your question, there is no intrinsic link.

SHA1 generation on .net4

I reused some old code and come saw that I had been using this code to generate a SHA1 hash.
HashAlgorithm sha = new SHA1CryptoServiceProvider();
return sha.ComputeHash((new UnicodeEncoding()).GetBytes(password.Trim()));
When I use the following code to generate a SHA1-hash I do not end up with the same hash as when I test with, for example, http://gtools.org/tool/sha1-hash-generator/
Which one is correct?
Am I doing something wrong here?
Most likely a difference in encoding. You're using UTF-16. Try using UTF-8.
Just confirmed that this site uses UTF-8. But their code is broken for certain characters, such as ', because they put their input through sql escaping.
But hashing a password with plain SHA-1 is almost never the correct choice. In most cases, such as storing passwords used for login to your site you should use a proper password hashing functions, such as PBKDF2, bcrypt or scrypt with an appropriate salt.
PBKDF2 is implemented in .net in the Rfc2898DeriveBytes Class
Example of SHA-1 salting:
return Convert.ToBase64String(
new HMACSHA1(
Encoding.UTF8.GetBytes(salt))
.ComputeHash(
Encoding.UTF8.GetBytes(input)));

Categories