2016-05-20 10 views
1

私はどちらが良い答えと一緒に大きなフィードバックを得たのかという質問をしました。私は、2つのハッシュの検証チェックで何か間違っていると仮定します。おそらくループ内のコードは問題ありませんが、バイトとbase64などを理解している私のコードは問題ですか?ハッシュパスワードの確認が機能していません

ここに元の質問があります。 Password Hashing - Why salt 60,000 times

問題は、これらのハッシュが一致していないですif (resultHash.Equals(hashPassword))

コード

public string BuildVerify() 
{ 

    string password = ""; 
    string salt = ""; 
    byte[] result; 


    using (var sha256 = SHA256.Create()) 
    { 
     password = "hovercraft"; 

     // step 1: you can use RNGCryptoServiceProvider for something worth using 
     var passwordHashing = new PasswordHashing(); 
     salt = passwordHashing.CreateRandomSalt(); 

     // step 2 
     string hash = 
      Convert.ToBase64String(sha256.ComputeHash(Encoding.UTF8.GetBytes(salt + password))); 

     // step 3 
     result = sha256.ComputeHash(Encoding.UTF8.GetBytes(salt + hash)); 

     // step 4 
     for (int i = 0; i < 60000; i++) 
     { 
      result = 
      sha256.ComputeHash(Encoding.UTF8.GetBytes(salt + Convert.ToBase64String(result))); 
     } 
    } 


    // TESTING VERIFY this works .. 

    string SaltAndPwd = string.Concat(password, salt); 
    SHA256 sha2 = SHA256Managed.Create(); 
    byte[] buff = sha2.ComputeHash(Encoding.Unicode.GetBytes(SaltAndPwd)); 
    string resultHash = Convert.ToBase64String(buff); 
    string hashPassword = Convert.ToBase64String(result); 

    if (resultHash.Equals(hashPassword)) 
    { 
     // perfect 
    } 





    return ""; 

} 


public class PasswordHashing 
{ 

    public string CreateRandomSalt() 
    { 
     string password = ""; 
     password = HashPassword.CreateSalt(8) + "="; 
     password = password.Replace("/", "c"); 
     return password; 
    } 

    } 

public static string CreateSalt(int size) 
{ 
    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); 

    byte[] buff = new byte[size]; 
    rng.GetBytes(buff); 
    return Convert.ToBase64String(buff); 
} 

アップデート - 問題

[OK]を、私は、答えからコードを使用していますが、私のコードを使って検証することができないので、明らかに私の前提は正しくありません。

  // This should be stored in your DB for example along with the hash result 
      var newsalt = SOPasswordHasher.GetSalt(); 

      // We calculate the hash then store the result. Next time you want to authenticate someone 
      // You'll have to reuse the same salt and recalculate the hash then compare 
      // the stored hash with the new one 
      var result = Convert.ToBase64String(SOPasswordHasher.Hash("hovercraft", newsalt)); 

      string SaltAndPwd = string.Concat("hovercraft", newsalt); 
      SHA256 sha2 = SHA256Managed.Create(); 
      byte[] buff = sha2.ComputeHash(Encoding.Unicode.GetBytes(SaltAndPwd)); 
      string resultHash = Convert.ToBase64String(buff); 

      if (result.Equals(resultHash)) 
      { 
       // perfect 
      } 
+0

ループ内のこの行があなたの検証と一致するかどうかは、あなたが言っていることからではありません。結果= sha256.ComputeHash(Encoding.UTF8.GetBytes(salt + Convert.ToBase64String(result))); –

+1

bcryptまたはPBKDFv2を使用してください。これはすべて正しいことです。 – SLaks

+0

@SLaks他の関連する質問から、彼自身の方法を使用することは彼の仕事からの必要条件です。 NIH症候群と思われる。 – Nasreddine

答えて

2

はここ(BASE64に変換するにはあまり頼ら)あなたが使用することができ、再利用可能なクラスです:

// This should be stored in your DB for example along with the hash result 
var salt = SOPasswordHasher.GetSalt(); 

// We calculate the hash then store the result. Next time you want to authenticate someone 
// You'll have to reuse the same salt and recalculate the hash then compare 
// the stored hash with the new one 
var result = Convert.ToBase64String(SOPasswordHasher.Hash("hovercraft", salt)); 

重要:

class SOPasswordHasher 
{ 
    /// <summary> 
    /// Password Hasher 
    /// </summary> 
    /// <param name="password">The password you want to hash</param> 
    /// <param name="salt">byte array of (crypto-secure) random values</param> 
    /// <param name="iterations">Number of iterations. default is 60,000</param> 
    /// <returns>Byte array containing the hashed password</returns> 

    public static byte[] Hash(string password, byte[] salt, int iterations = 60000) 
    { 
     using (var sha256 = SHA256.Create()) 
     { 
      byte[] passwordBytes = Encoding.UTF8.GetBytes(password); 

      // step 2 
      byte[] hash = sha256.ComputeHash(passwordBytes.Concat(salt).ToArray()); 

      // step 3 
      byte[] result = sha256.ComputeHash(salt.Concat(hash).ToArray()); 

      // step 4 
      for (int i = 0; i < iterations; i++) 
      { 
       result = 
        sha256.ComputeHash(salt.Concat(result).ToArray()); 
      } 

      return result; 
     } 
    } 

    public static byte[] GetSalt(int size = 32) 
    { 
     byte[] salt = new byte[size]; 
     using (var cryptoServiceProvider = new RNGCryptoServiceProvider()) 
     { 
      cryptoServiceProvider.GetBytes(salt); 
     } 
     return salt; 
    } 
} 

、ここでは使用例ですノー作ります私はではないので、このコードは安全であることを保証します。はセキュリティ専門家です。 Bruce Schneier氏は最高だと言っています。"Amateurs Produce Amateur Cryptography"

+0

作成されたハッシュをまだ検証/検証できない。上記のコードを下の質問に投稿します。 –

+0

var result = Convert.ToBase64String(SOPasswordHasher.Hash( "hovercraft"、newsalt)); 文字列SaltAndPwd = string.Concat( "hovercraft"、newsalt); SHA256 sha2 = SHA256Managed.Create(); byte [] buff = sha2.ComputeHash(Encoding.Unicode.GetBytes(SaltAndPwd)); string resultHash = Convert.ToBase64String(buff); if(result.Equals(resultHash)) { //完全 } –

+0

「確認する」ことを私は確信していません。あなたの 'buff'変数を生成するために使っているメソッドは、' Hash'メソッドで使われているものと一致しません。彼らがマッチする理由はありません。 – Nasreddine

関連する問題