Apr 25, 2016 07:19 AM
(This post was last modified: Apr 25, 2016 07:20 AM by morphine1337.)
Hello, i need a method to hash a string so it will give me the same output as PHP Code
<?php hash_pbkdf2('SHA256', $key, $salt, 1000, 32);
from php.
I know it has to do with Rfc2898DeriveBytes but i cant make it work
A small example of Rfc2898DeriveBytes :
PHP Code
<?php public static string HashPassword(string password) { // Generate the hash, with an automatic 32 byte salt Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, 32); rfc2898DeriveBytes.IterationCount = 10000; byte[] hash = rfc2898DeriveBytes.GetBytes(20); byte[] salt = rfc2898DeriveBytes.Salt; //Return the salt and the hash return Convert.ToBase64String(salt) + "|" + Convert.ToBase64String(hash); }
Another example :
( Source : https://cmatskas.com/-net-password-hashi...ng-pbkdf2/ )
PHP Code
<?php public class PasswordHash { public const int SaltByteSize = 24; public const int HashByteSize = 20; // to match the size of the PBKDF2-HMAC-SHA-1 hash public const int Pbkdf2Iterations = 1000; public const int IterationIndex = 0; public const int SaltIndex = 1; public const int Pbkdf2Index = 2;
public static string HashPassword(string password) { var cryptoProvider = new RNGCryptoServiceProvider(); byte[] salt = new byte[SaltByteSize]; cryptoProvider.GetBytes(salt);
var hash = GetPbkdf2Bytes(password, salt, Pbkdf2Iterations, HashByteSize); return Pbkdf2Iterations + ":" + Convert.ToBase64String(salt) + ":" + Convert.ToBase64String(hash); }
public static bool ValidatePassword(string password, string correctHash) { char[] delimiter = { ':' }; var split = correctHash.Split(delimiter); var iterations = Int32.Parse(split[IterationIndex]); var salt = Convert.FromBase64String(split[SaltIndex]); var hash = Convert.FromBase64String(split[Pbkdf2Index]);
var testHash = GetPbkdf2Bytes(password, salt, iterations, hash.Length); return SlowEquals(hash, testHash); }
private static bool SlowEquals(byte[] a, byte[] b) { var diff = (uint)a.Length ^ (uint)b.Length; for (int i = 0; i < a.Length && i < b.Length; i++) { diff |= (uint)(a[i] ^ b[i]); } return diff == 0; } private static byte[] GetPbkdf2Bytesstring password, byte[] salt, int iterations, int outputBytes) { var pbkdf2 = new Rfc2898DeriveBytes(password, salt); pbkdf2.IterationCount = iterations; return pbkdf2.GetBytes(outputBytes); } }
You can find an example here :
http://lockmedown.com/hash-right-impleme...bkdf2-net/
Hope this helps !
🤝
I know how to use Rfc2898DeriveBytes. But its default algorithm for hashing is sha1 and i need sha256. So my question is: how to use Rfc2898DeriveBytes with another hashing algo, specifically sha256 ?
(Apr 25, 2016 10:24 AM)morphine1337 Wrote: I know how to use Rfc2898DeriveBytes. But its default algorithm for hashing is sha1 and i need sha256. So my question is: how to use Rfc2898DeriveBytes with another hashing algo, specifically sha256 ?
Rfc2898DeriveBytes is unfortunately not configurable to use a different hash function as far that i know of, so you'll have to make your own functionality.
This is what i found doing a little search :
PHP Code
<?php // NOTE: The iteration count should // be as high as possible without causing // unreasonable delay. Note also that the password // and salt are byte arrays, not strings. After use, // the password and salt should be cleared (with Array.Clear) public static byte[] PBKDF2Sha256GetBytes(int dklen, byte[] password, byte[] salt, int iterationCount){ using(var hmac=new System.Security.Cryptography.HMACSHA256(password)){ int hashLength=hmac.HashSize/8; if((hmac.HashSize&7)!=0) hashLength++; int keyLength=dklen/hashLength; if((long)dklen>(0xFFFFFFFFL*hashLength) || dklen<0) throw new ArgumentOutOfRangeException("dklen"); if(dklen%hashLength!=0) keyLength++; byte[] extendedkey=new byte[salt.Length+4]; Buffer.BlockCopy(salt,0,extendedkey,0,salt.Length); using(var ms=new System.IO.MemoryStream()){ for(int i=0;i<keyLength;i++){ extendedkey[salt.Length]=(byte)(((i+1)>>24)&0xFF); extendedkey[salt.Length+1]=(byte)(((i+1)>>16)&0xFF); extendedkey[salt.Length+2]=(byte)(((i+1)>>8)&0xFF); extendedkey[salt.Length+3]=(byte)(((i+1))&0xFF); byte[] u=hmac.ComputeHash(extendedkey); Array.Clear(extendedkey,salt.Length,4); byte[] f=u; for(int j=1;j<iterationCount;j++){ u=hmac.ComputeHash(u); for(int k=0;k<f.Length;k++){ f[k]^=u[k]; } } ms.Write(f,0,f.Length); Array.Clear(u,0,u.Length); Array.Clear(f,0,f.Length); } byte[] dk=new byte[dklen]; ms.Position=0; ms.Read(dk,0,dklen); ms.Position=0; for(long i=0;i<ms.Length;i++){ ms.WriteByte(0); } Array.Clear(extendedkey,0,extendedkey.Length); return dk; } }
You could also use Bouncy Castle. The C# specification lists the algorithm "PBEwithHmacSHA-256", which can only be PBKDF2 with SHA-256.
🤝
http://stackoverflow.com/a/18649357 is source for the above code. Just want to make sure author gets proper credit.
Need a custom software? Check out my freelance service here! 6+ years and counting, never a complaint :)
STOP STEALING CODE.
FREE NATHAN
People who report posts are lamers.
|