尝试使用C#.Net对HMAC-SHA256进行编码

我尝试将HMAC-SHA256算法编码为函数

HMAC(K,m)= H((K⊕opad)∥H((K⊕ipad)∥m))

哪里

  • H是加密哈希函数,
  • K是一个填充到右侧的密钥,对散列函数的输入块大小加上额外的零,或者如果它比块大小长,则为原始密钥的散列,
  • m是要进行身份validation的消息,
  • ∥表示连接,
  • ⊕表示独占或(XOR),
  • opad是外部填充(0x5c5c5c … 5c5c,一个块长的hex常量),
  • ipad是内部填充(0x363636 … 3636,一个块长的hex常量)。

这是我的代码

public static string MyHMACHash(string key , string message) { Encoding encoding = Encoding.UTF8; //var md = System.Security.Cryptography.MD5CryptoServiceProvider.Create(); SHA256 hash = SHA256Managed.Create(); byte[] trans_5C = new byte[32]; byte[] trans_36 = new byte[32]; byte[] b_key = encoding.GetBytes(key); // TODO: also check if key is to short if (b_key.Length > 32) b_key = hash.ComputeHash(b_key); for (int i = 0; i < 32; i++) { trans_5C[i] = 92; trans_36[i] = 54; if (i < key.Length) { trans_5C[i] ^= b_key[i]; trans_36[i] ^= b_key[i]; } } byte[] inner = hash.ComputeHash(trans_36.Concat(encoding.GetBytes(message)).ToArray()); var Fhash = hash.ComputeHash(trans_5C.Concat(inner).ToArray()); StringBuilder sb = new StringBuilder(); foreach (byte b in Fhash) sb.Append(b.ToString("x2")); string result = sb.ToString(); // = 9036a1a3f654aefeab426e9f7e17288e return result; } 

但当我尝试测试此代码时,结果不符合标准互联网网站上的标准HMAC-SHA256哈希

以下是具有自定义HMAC生成的修改版本。 要考虑的主要是K中引用的输入块大小是散列算法块大小; 没有返回散列字节长度。 对于SHA256,块大小为64字节。 我相信你使用32字节块大小。 您可以在此处找到不同的块大小参考: http : //en.wikipedia.org/wiki/Secure_Hash_Algorithm 。

 public static string MyHMACHash(string key, string message) { Encoding encoding = Encoding.UTF8; //Reference http://en.wikipedia.org/wiki/Secure_Hash_Algorithm //SHA256 block size is 512 bits => 64 bytes. const int HashBlockSize = 64; var keyBytes = encoding.GetBytes(key); var opadKeySet = new byte[HashBlockSize]; var ipadKeySet = new byte[HashBlockSize]; if (keyBytes.Length > HashBlockSize) { keyBytes = GetHash(keyBytes); } // This condition is independent of previous // condition. If previous was true // we still need to execute this to make keyBytes same length // as blocksize with 0 padded if its less than block size if (keyBytes.Length < HashBlockSize) { var newKeyBytes = new byte[HashBlockSize]; keyBytes.CopyTo(newKeyBytes, 0); keyBytes = newKeyBytes; } for (int i = 0; i < keyBytes.Length; i++) { opadKeySet[i] = (byte)(keyBytes[i] ^ 0x5C); ipadKeySet[i] = (byte)(keyBytes[i] ^ 0x36); } var hash = GetHash(ByteConcat(opadKeySet, GetHash(ByteConcat(ipadKeySet, encoding.GetBytes(message))))); // Convert to standard hex string return hash.Select(a => a.ToString("x2")) .Aggregate((a, b) => string.Format("{0}{1}", a, b)); } public static byte[] GetHash(byte[] bytes) { using (var hash = new SHA256Managed()) { return hash.ComputeHash(bytes); } } public static byte[] ByteConcat(byte[] left, byte[] right) { if (null == left) { return right; } if (null == right) { return left; } byte[] newBytes = new byte[left.Length + right.Length]; left.CopyTo(newBytes, 0); right.CopyTo(newBytes, left.Length); return newBytes; }