How to hash a password with SHA512 - c#

In my previous question I was told to hash passwords instead of encrypt, and that turned out to be correct. Problem is, I've never dealt with hashing passwords before and all the docs say SHA512 which I've tried to use on a test account to no avail. I'm not sure where to go from here. The code comments give me the example "encrypted" string as they call it, and it's "FA35A0194E3BE7024CEFB1839CBFC922" which I'm not sure how to format it like that with SHA512 since all it takes and gives back is a byte array or stream from the ComputeHash() method:
byte[] hashedPassword = HashAlgorithm.Create("SHA512").ComputeHash( ??? );
UPDATE
I've tried printing out the UTF8Encoding.GetString on the bytes, but it just displays a bunch of bullshit characters that look nothing like the one in the example docs.

Hashing with plain SHA-512 is still wrong. Use PBKDF2 which is exposed via Rfc2898DeriveBytes.
It returns raw bytes, which you should encode with either hex or base64.
You can do hex encoding with:
BitConverter.ToString(bytes).Replace("-","")

You sure it said 512 because that's 128, but anyway you could use something like
System.String Hashed = System.BitConverter.ToString(((System.Security.Cryptography.SHA512)new System.Security.Cryptography.SHA512Managed()).ComputeHash(System.Text.Encoding.ASCII.GetBytes("NotHashedPass"))).Replace("-","");
MessageBox.Show(Hashed);
but id recommend at least using a salt.

Please see tutorial here:
http://www.obviex.com/samples/hash.aspx
From the tutorial:
"These code samples demonstrate how to hash data and verify hashes. It supports several hashing algorithms. To help reduce the risk of dictionary attacks, the code prepends random bytes (so-called salt) to the original plain text before generating hashes and appends them to the generated ciphertext (original salt value will be needed for hash verification). The resulting ciphertext is base64-encoded. IMPORTANT: DATA HASHES CANNOT BE DECRYPTED BACK TO PLAIN TEXT"

Related

Fast checking for encrypted values by X509Certificate2

I have many different string values in a collection.
Some values were encrypted by X509Certificate2. All other values are numbers, non encrypted strings, dates, etc.
My goal to filter possible candidates for decryption. So I want to use a function that can implement first fast filtration of values that were encrypted.
I use this simple check:
private bool IsEncryptedValue(string value)
{
var result = !string.IsNullOrEmpty(value) && IsBase64String(value);
return result;
}
Please advise more correct (more strong) rules for checking encrypted value.
Thanks for any suggestions.
Ciphertext of any modern cipher is binary. If the ciphertext is in a string I would expect that it has been encoded using base 64 (or a dialect) or hexadecimals. Once you've decoded that it should be exactly be the key size if direct RSA encryption has been used. If a hybrid cryptosystem has been used then it should be at least the key size.
Of course, you will have to find out which RSA encryption scheme was used, and in the case of hybrid encryption you'd have to find out which symmetric encryption scheme was used as well. It might be that the encryption uses a known container format such as CMS or PGP, so you could scan for that as well.
Finally, although it is unlikely: in principle the outcome of RSA encryption is a number. If that number is stored in decimals then it should have keysize / 3.32192809 or fewer digits.
In principle the outcome of a cipher is randomized, so we don't have much to separate it from any other encoding. You can try and validate that it is randomized, but if you've only a small ciphertext then estimating the amount of randomness is relatively tricky - so I've not included that in my answer.
This is a strange endeavor though, generally you'd know if something is a ciphertext or not.

AES Encryption in windows phone 8

I am trying to do AES Encryption in my windows phone8 app.
I searched a lot, but couldn't get a clear view to do so.
Can anybody give me link that gives the clear example of implementing AES Encryption ni WP8 App.
What i need to do is,
1)I need to pass key, initial vector, and value as strings.
2)need to encrypt that string in any format of AES Encryption, and finally need to get the encrypted value as string.
Can anybody help me.
am using this example and using UTF8 encoding for key, and Iv
myAes.Key = Encoding.UTF8.GetBytes("terr!f!cp#ssw0rdw!thonetw!st!n!t");
myAes.IV = Encoding.UTF8.GetBytes("1234567890987654");
and after encoding to convert the bytes of encrypted value to string am using ToBase64 convertion
afterText.Text = Convert.ToBase64String(encrypted);
here i need to tell my back end team, what the exact encryption am using here, am not sure about what is happening here, Can you please tell me whats that exact encryption happening here.
Thank you.
The CryptographicBuffer Class is your friend:
Use Hex or Base64 encoding for binary values you want to represent as strings. This includes Key, IV and ciphertext
Use UTF-8 for text you want to turn to bytes.

Can someone explain how BCrypt verifies a hash?

I'm using C# and BCrypt.Net to hash my passwords.
For example:
string salt = BCrypt.Net.BCrypt.GenerateSalt(6);
var hashedPassword = BCrypt.Net.BCrypt.HashPassword("password", salt);
//This evaluates to True. How? I'm not telling it the salt anywhere, nor
//is it a member of a BCrypt instance because there IS NO BCRYPT INSTANCE.
Console.WriteLine(BCrypt.Net.BCrypt.Verify("password", hashedPassword));
Console.WriteLine(hashedPassword);
How is BCrypt verifying the password with the hash if it's not saving the salt anywhere. The only idea I have is that it's somehow appending the salt at the end of the hash.
Is this a correct assumption?
A BCrypt hash string looks like:
$2a$10$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm
\__/\/ \____________________/\_____________________________/
| | Salt Hash
| Cost
Version
Where
2a: Algorithm Identifier (BCrypt, UTF8 encoded password, null terminated)
10: Cost Factor (210 = 1,024 rounds)
Ro0CUfOqk6cXEKf3dyaM7O: OpenBSD-Base64 encoded salt (22 characters, 16 bytes)
hSCvnwM9s4wIX9JeLapehKK5YdLxKcm: OpenBSD-Base64 encoded hash (31 characters, 24 bytes)
Edit: i just noticed these words fit exactly. i had to share:
$2a$10$TwentytwocharactersaltThirtyonecharacterspasswordhash
$==$==$======================-------------------------------
BCrypt does create a 24-byte binary hash, using 16-byte salt. You're free to store the binary hash and the salt however you like; nothing says you have to base-64 encode it into a string.
But BCrypt was created by guys who were working on OpenBSD. OpenBSD already defines a format for their password file:
$[HashAlgorithmIdentifier]$[AlgorithmSpecificData]
This means that the "bcrypt specification" is inexorably linked to the OpenBSD password file format. And whenever anyone creates a "bcrypt hash" they always convert it to an ISO-8859-1 string of the format:
$2a$[Cost]$[Base64Salt][Base64Hash]
A few important points:
2a is the algorithm identifier
1: MD5
2: early bcrypt, which had confusion over which encoding passwords are in (obsolete)
2a: current bcrypt, which specifies passwords as UTF-8 encoded
Cost is a cost factor used when computing the hash. The "current" value is 10, meaning the internal key setup goes through 1,024 rounds
10: 210 = 1,024 iterations
11: 211 = 2,048 iterations
12: 212 = 4,096 iterations
the base64 algorithm used by the OpenBSD password file is not the same Base64 encoding that everybody else uses; they have their own:
Regular Base64 Alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
BSD Base64 Alphabet: ./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
So any implementations of bcrypt cannot use any built-in, or standard, base64 library
Armed with this knowledge, you can now verify a password correctbatteryhorsestapler against the saved hash:
$2a$12$mACnM5lzNigHMaf7O1py1O3vlf6.BA8k8x3IoJ.Tq3IB/2e7g61Km
BCrypt variants
There is a lot of confusion around the bcrypt versions.
$2$
BCrypt was designed by the OpenBSD people. It was designed to hash passwords for storage in the OpenBSD password file. Hashed passwords are stored with a prefix to identify the algorithm used. BCrypt got the prefix $2$.
This was in contrast to the other algorithm prefixes:
$1$: MD5
$5$: SHA-256
$6$: SHA-512
$2a$
The original BCrypt specification did not define how to handle non-ASCII characters, or how to handle a null terminator. The specification was revised to specify that when hashing strings:
the string must be UTF-8 encoded
the null terminator must be included
$2x$, $2y$ (June 2011)
A bug was discovered in crypt_blowfish🕗, a PHP implementation of BCrypt. It was mis-handling characters with the 8th bit set.
They suggested that system administrators update their existing password database, replacing $2a$ with $2x$, to indicate that those hashes are bad (and need to use the old broken algorithm). They also suggested the idea of having crypt_blowfish emit $2y$ for hashes generated by the fixed algorithm. Nobody else, including canonical OpenBSD, adopted the idea of 2x/2y. This version marker was was limited to crypt_blowfish🕗.
The versions $2x$ and $2y$ are not "better" or "stronger" than $2a$. They are remnants of one particular buggy implementation of BCrypt.
$2b$ (February 2014)
A bug was discovered in the OpenBSD implementation of BCrypt. They wrote their implementation in a language that doesn't have support strings - so they were faking it with a length-prefix, a pointer to a character, and then indexing that pointer with []. Unfortunately they were storing the length of their strings in an unsigned char. If a password was longer than 255 characters, it would overflow and wrap at 255. BCrypt was created for OpenBSD. When they have a bug in their library, they decided its ok to bump the version. This means that everyone else needs to follow suit if you want to remain current to "their" specification.
http://undeadly.org/cgi?action=article&sid=20140224132743 🕗
http://marc.info/?l=openbsd-misc&m=139320023202696 🕗
There is no difference between 2a, 2x, 2y, and 2b. If you wrote your implementation correctly, they all output the same result.
If you were doing the right thing from the beginning (storing strings in utf8 and also hashing the null terminator) then: there is no difference between 2, 2a, 2x, 2y, and 2b. If you wrote your implementation correctly, they all output the same result.
The version $2b$ is not "better" or "stronger" than $2a$. It is a remnant of one particular buggy implementation of BCrypt. But since BCrypt canonically belongs to OpenBSD, they get to change the version marker to whatever they want.
The versions $2x$ and $2y$ are not better, or even preferable, to anything. They are remnants of a buggy implementation - and should summarily forgotten.
The only people who need to care about 2x and 2y are those you may have been using crypt_blowfish back in 2011. And the only people who need to care about 2b are those who may have been running OpenBSD.
All other correct implementations are identical and correct.
How is BCrypt verifying the password with the hash if it's not saving the salt anywhere?
Clearly it is not doing any such thing. The salt has to be saved somewhere.
Let's look up password encryption schemes on Wikipedia. From http://en.wikipedia.org/wiki/Crypt_(Unix) :
The output of the function is not merely the hash: it is a text string which also encodes the salt and identifies the hash algorithm used.
Alternatively, an answer to your previous question on this subject included a link to the source code. The relevant section of the source code is:
StringBuilder rs = new StringBuilder();
rs.Append("$2");
if (minor >= 'a') {
rs.Append(minor);
}
rs.Append('$');
if (rounds < 10) {
rs.Append('0');
}
rs.Append(rounds);
rs.Append('$');
rs.Append(EncodeBase64(saltBytes, saltBytes.Length));
rs.Append(EncodeBase64(hashed,(bf_crypt_ciphertext.Length * 4) - 1));
return rs.ToString();
Clearly the returned string is version information, followed by the number of rounds used, followed by the salt encoded as base64, followed by the hash encoded as base64.

Salted hash algorithm

I am using salted hash algorithm to secure the password. RNGCryptoServiceProvider is used to create the salt. Is it possible to create salt based on the user name? Please help me
You should first of all look into what Salt is then you could revise this greate code-chunk to see how you use Cryptography with Salt in unfortunatly VB.
Now that you are familiar with how Salt works and have some knowledge of the C# implementation. You see that it actually is possible to do some modifications with the salting. For instance the computeHash takes a byte[] for salting, maybe you could try
System.Text.ASCIIEncoding encoding=new System.Text.ASCIIEncoding();
encoding.GetBytes(str);
There is a world of possibilites for you, but to simply answer your question without spoiling the ending, yes, you can create a salt based on the username.

How can I unhash a hash using C#?

Can someone reverse this handy hash code I'm using?
using System.Security.Cryptography;
public static string EncodePasswordToBase64(string password)
{ byte[] bytes = Encoding.Unicode.GetBytes(password);
byte[] inArray = HashAlgorithm.Create("SHA1").ComputeHash(bytes);
return Convert.ToBase64String(inArray);
}
Everything I end up doing fails horribly :(.
No, you can't reverse a hash. The typical process is to compare other input to the hash you have, to check if they are the same.
Like (pseudo):
initial = Hash(password);
possible = Hash("test");
if( initial == possible ){
// we infer that password = "test"
}
But note that SHA1, SHA0, and MD5 should no longer be used; (due to various degrees of breaking in each). You should use SHA-2
The only real way of "unhashing" is using a rainbow table, which is a big table of hashes computed for all possible inputs. You look up the hash and get what was probably the original input.
http://en.wikipedia.org/wiki/Rainbow_table
You cannot un-hash SHA1, MD5, or any other one-way hash method unfortunately. Though it is possible to undo BASE-64.
SHA is an NSA acronym for "Secure Hash Algorithm".
Secure Hashes are hard to reverse by definition -- otherwise they would not be Secure.
You need to use a reversible hash function if you want to be able to easily compute sources that will generate the same hash (and even then you might not get the original source due to hash collisions where more than one source input can result in the same hash output).

Categories

Resources