2012-01-11 64 views
3

我真的是新的C#和我在看我的前任生成的代码。下面的代码:设置额外的哈希算法

public static string ComputeHash(string plainText, 
            string hashAlgorithm, byte[] saltBytes) 
    { 
     if (saltBytes == null) 
      saltBytes = CreateSalt(8); 

     // Convert plain text into a byte array. 
     byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); 

     // Allocate array, which will hold plain text and salt. 
     byte[] plainTextWithSaltBytes = 
       new byte[plainTextBytes.Length + saltBytes.Length]; 

     // Copy plain text bytes into resulting array. 
     for (int i = 0; i < plainTextBytes.Length; i++) 
      plainTextWithSaltBytes[i] = plainTextBytes[i]; 

     // Append salt bytes to the resulting array. 
     for (int i = 0; i < saltBytes.Length; i++) 
      plainTextWithSaltBytes[plainTextBytes.Length + i] = saltBytes[i]; 

     // Because we support multiple hashing algorithms, we must define 
     // hash object as a common (abstract) base class. We will specify the 
     // actual hashing algorithm class later during object creation. 
     HashAlgorithm hash; 

     // Make sure hashing algorithm name is specified. 
     if (hashAlgorithm == null) 
      hashAlgorithm = ""; 

     // Initialize appropriate hashing algorithm class. 
     switch (hashAlgorithm.ToUpper()) 
     { 
      case "SHA1": 
       hash = new SHA1Managed(); 
       break; 

      case "SHA256": 
       hash = new SHA256Managed(); 
       break; 

      case "SHA384": 
       hash = new SHA384Managed(); 
       break; 

      case "SHA512": 
       hash = new SHA512Managed(); 
       break; 

      default: 
       hash = new MD5CryptoServiceProvider(); 
       break; 
     } 

     // Compute hash value of our plain text with appended salt. 
     byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes); 

     // Create array which will hold hash and original salt bytes. 
     byte[] hashWithSaltBytes = new byte[hashBytes.Length + 
              saltBytes.Length]; 

     // Copy hash bytes into resulting array. 
     for (int i = 0; i < hashBytes.Length; i++) 
      hashWithSaltBytes[i] = hashBytes[i]; 

     // Append salt bytes to the result. 
     for (int i = 0; i < saltBytes.Length; i++) 
      hashWithSaltBytes[hashBytes.Length + i] = saltBytes[i]; 

     // Convert result into a base64-encoded string. 
     string hashValue = Convert.ToBase64String(hashWithSaltBytes); 

     // Return the result. 
     return hashValue; 
    } 

    public static bool VerifyHash(string plainText, 
            string hashAlgorithm, 
            string hashValue) 
    { 
     // Convert base64-encoded hash value into a byte array. 
     byte[] hashWithSaltBytes = Convert.FromBase64String(hashValue); 

     // We must know size of hash (without salt). 
     int hashSizeInBits, hashSizeInBytes; 

     // Make sure that hashing algorithm name is specified. 
     if (hashAlgorithm == null) 
      hashAlgorithm = ""; 

     // Size of hash is based on the specified algorithm. 
     switch (hashAlgorithm.ToUpper()) 
     { 
      case "SHA1": 
       hashSizeInBits = 160; 
       break; 

      case "SHA256": 
       hashSizeInBits = 256; 
       break; 

      case "SHA384": 
       hashSizeInBits = 384; 
       break; 

      case "SHA512": 
       hashSizeInBits = 512; 
       break; 

      default: // Must be MD5 
       hashSizeInBits = 128; 
       break; 
     } 

     // Convert size of hash from bits to bytes. 
     hashSizeInBytes = hashSizeInBits/8; 

     // Make sure that the specified hash value is long enough. 
     if (hashWithSaltBytes.Length < hashSizeInBytes) 
      return false; 

     // Allocate array to hold original salt bytes retrieved from hash. 
     byte[] saltBytes = new byte[hashWithSaltBytes.Length - 
            hashSizeInBytes]; 

     // Copy salt from the end of the hash to the new array. 
     for (int i = 0; i < saltBytes.Length; i++) 
      saltBytes[i] = hashWithSaltBytes[hashSizeInBytes + i]; 

     // Compute a new hash string. 
     string expectedHashString = 
        ComputeHash(plainText, hashAlgorithm, saltBytes); 

     // If the computed hash matches the specified hash, 
     // the plain text value must be correct. 
     return (hashValue == expectedHashString); 
    } 

该公司已经升级了他们的安全标准和要求的安全散列算法如SHA-1,3DES(三重DES)或AES MAC。我不知道在哪里包含它们。有人请帮忙吗?

+3

3DES不是散列算法......而AES MAC听起来像是MAC,而不是散列。 – 2012-01-11 15:40:39

+0

@KerrekSB与3DES不是3DES相同吗?我认为这是一种哈希算法。而不是基于Poly1305-AES的MAC(消息认证码)?如果我错了,请纠正我,因为我对这一切真的很陌生。 – 2012-01-11 15:57:30

+4

你一定要在密码主题上保持一个非常广泛的位置,直到你对这个问题有一个非常坚定的理解,并且可以自己回答这些问题! (3DES(=三重DES)是*密码*; MAC是MAC,而不是散列 - 可以使用散列(例如HMAC)*设计* MAC,但这是一个单独的主题。 – 2012-01-11 16:00:17

回答

1

我以“AES MAC”假设你指的是Poly1305-AES。 Poly1305-AES不是一个简单的散列,它需要一个AES密钥和一个128位的nonce,在两个实体之间进行通信时使用。

3DES(Triple DES)是一种加密密码,它不能确保消息的认证或完整性。 3DES的唯一功能是确保消息的机密性。

在对于SHA-1,你不应该再使用散列,因为它已经broken自2005年以来

我会建议你得到的是什么,这些新的安全标准是一个正式的说明。你列出的事情中有2个甚至不是散列算法,第三个是不好的选择。在当前实现中列出的哈希算法中,SHA-256和更高版本应该没问题(又名SHA-2类别)。这些没有我目前知道的任何已发布的漏洞。

备注:您可能希望使用arraycopy而不是循环遍历字节。

2

该公司已经升级了他们的安全标准,并要求安全散列算法,如SHA-1,3DES(三重DES)或AES MAC。

首先,你已经有SHA-1,那个散列算法虽然稍微弱于SHA-256/512,但还是相当不错的。坚持SHA-512 will keep you very safe,除非你正在处理那些愿意花费10年时间使用超级计算机来破坏你的消息的恶棍。

至于其他两种算法,3DES是对称暗号,并且因此不适合用于散列,而MACs使用散列算法,例如SHA-2中创建(所不同的是你散列你“秘密密钥”沿着您的留言(类似“固定盐”),以确保其真实性。AES也是对称的暗号,因此也不适合散列。

告诉家伙从你的公司检查this page和解决对这些散列函数之一(换句话说:不要改变任何东西),如果你没有使用密码技术,你可能会让系统不安全,不管你有没有兴选择。