Attualmente stiamo utilizzando HMACSHA512 in .net, con una chiave di convalida 128Char (64byte) Il sale è 64 caratteri generati casualmente stringa. Abbiamo assegnato 2048 lunghezza al database per il risultato della stringa base64 hash. Sarà un sito Web pubblico. Questo approccio è ragionevole o dovrebbe essere modificato in un altro approccio come Rfc2898DeriveBytes?
public string HashEncode(string password, string salt, string validationKey) {
byte[] hashKey = BosUtilites.HexStringToByteArray(validationKey);
var sha512 = new HMACSHA512(hashKey);
var hashInput = BosUtilites.StringToByteArray(password + salt);
byte[] hash = sha512.ComputeHash(hashInput);
return Convert.ToBase64String(hash);
}
public string GenerateSimpleSalt(int Size = 64) {
var alphaSet = new char[64]; // use 62 for strict alpha... that random generator for alphas only
//nicer results with set length * int i = 256. But still produces excellent random results.
//alphaset plus 2. Reduce to 62 if alpha requried
alphaSet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890#=".ToCharArray();
var tempSB = GenerateRandomString(Size, alphaSet);
return tempSB.ToString();
}
public StringBuilder GenerateRandomString(int Size, char[] alphaSet) {
using (var crypto = new RNGCryptoServiceProvider()) {
var bytes = new byte[Size];
crypto.GetBytes(bytes); //get a bucket of very random bytes
var tempSB = new StringBuilder(Size);
foreach (var b in bytes) { // use b , a random from 0-255 as the index to our source array. Just mod on length set
tempSB.Append(alphaSet[b%(alphaSet.Length)]);
}
return tempSB;
}
EDIT2: nel caso in cui qualcuno lo trovi tramite google, ho incluso le lezioni apprese Il campione medio nei test sulle workstation era di circa 300 msec. Questo non dovrebbe essere troppo evidente durante l'accesso. E non c'è più bisogno di una chiave di convalida. Che è un sollievo: -)
SCrypt package installed via nuget. and rfc2898 PBKDF2 changed to be large number or iterations but only 20bytes output. SAme CPU time.
Le nuove password sono codificate in SCRYPT per impostazione predefinita,
<package id="CryptSharpOfficial" version="2.0.0.0" targetFramework="net451" />
// save salt, hash algorithm used and resulting encoding on user record
public string PasswordEncode(string password, byte[] salt, HashAlgorithm hashAlgorithm ) {
switch (hashAlgorithm) {
case HashAlgorithm.PBKDF2:
var deriver2898 = new Rfc2898DeriveBytes(password, salt,<Use a number around 50K>); // approx 300msecs on workstation
byte[] hash = deriver2898.GetBytes(20); //
return Convert.ToBase64String(hash);
case HashAlgorithm.Scrypt:
var key = Encoding.UTF8.GetBytes(password);
byte[] hashScrypt = SCrypt.ComputeDerivedKey(key: key, salt: salt,
cost: 65536, // must be a power of 2 !, on PC, singlethread this is approx 1 sec
blockSize: 8,
parallel: 1,
maxThreads: 1,
derivedKeyLength: 128);
return Convert.ToBase64String(hashScrypt);
default:
throw new ArgumentOutOfRangeException("hashAlgorithm");
}
}