如何在C#中生成HMAC-SHA1?

我正在尝试使用C#使用REST API。 API创build者已经提供了PHP,Ruby和Java的示例库。 我正在挂上它的一部分,我需要生成一个HMAC

以下是他们提供的示例库中的工作方式。

PHP

 hash_hmac('sha1', $signatureString, $secretKey, false); 

ruby

 digest = OpenSSL::Digest::Digest.new('sha1') return OpenSSL::HMAC.hexdigest(digest, secretKey, signatureString) 

Java的

 SecretKeySpec signingKey = new SecretKeySpec(secretKey.getBytes(), HMAC_SHA1_ALGORITHM); Mac mac = null; mac = Mac.getInstance(HMAC_SHA1_ALGORITHM); mac.init(signingKey); byte[] bytes = mac.doFinal(signatureString.getBytes()); String form = ""; for (int i = 0; i < bytes.length; i++) { String str = Integer.toHexString(((int)bytes[i]) & 0xff); if (str.length() == 1) { str = "0" + str; } form = form + str; } return form; 

这是我在C#中的尝试。 它不工作。 更新:下面的C#示例工作正常。 我发现真正的问题是由于我的signatureString中换行字符的一些跨平台差异。

 var enc = Encoding.ASCII; HMACSHA1 hmac = new HMACSHA1(enc.GetBytes(secretKey)); hmac.Initialize(); byte[] buffer = enc.GetBytes(signatureString); return BitConverter.ToString(hmac.ComputeHash(buffer)).Replace("-", "").ToLower(); 

Vimvq1987答案的扩展:

return hashValue.ToString(); 不会产生你想要/需要的输出。 您必须将数组hashValue的字节转换为它们的hexstring表示forms。
可以像return BitConverter.toString(hashValue);一样简单return BitConverter.toString(hashValue); (打印大写字母自动对焦)或者如果你喜欢它更复杂一点:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security.Cryptography; using System.IO; namespace ConsoleApplication1 { class Program { public static string Encode(string input, byte[] key) { HMACSHA1 myhmacsha1 = new HMACSHA1(key); byte[] byteArray = Encoding.ASCII.GetBytes(input); MemoryStream stream = new MemoryStream(byteArray); return myhmacsha1.ComputeHash(stream).Aggregate("", (s, e) => s + String.Format("{0:x2}",e), s => s ); } static void Main(string[] args) { byte[] key = Encoding.ASCII.GetBytes("abcdefghijklmnopqrstuvwxyz"); string input = ""; foreach (string s in new string[] { "Marry", " had", " a", " little", " lamb" }) { input += s; System.Console.WriteLine( Encode(input, key) ); } return; } } } 

打印

 3545e064fb59bc4bfc02b6e1c3d4925c898aa504 3249f4c8468d4d67f465937da05b809eaff22fdb 87baaadf5d096677f944015e53d283834eb1e943 6325376820c29a09e3ab30db000033aa71d6927d 54579b0146e2476595381d837ee38863be358213 

和我得到完全相同的结果

 <?php $secretKey = 'abcdefghijklmnopqrstuvwxyz'; $signatureString = ''; foreach( array('Marry',' had',' a',' little',' lamb') as $s ) { $signatureString .= $s; echo hash_hmac('sha1', $signatureString, $secretKey, false), "\n"; } 

编辑: 德米特里Nemykinbuild议以下编辑

 public static string Encode(string input, byte[] key) { byte[] byteArray = Encoding.ASCII.GetBytes(input); using(var myhmacsha1 = new HMACSHA1(key)) { var hashArray = myhmacsha1.ComputeHash(byteArray); return hashArray.Aggregate("", (s, e) => s + String.Format("{0:x2}",e), s => s ); } } 

被拒绝了。 但是正如詹姆斯在对这个答案的评论中已经指出的那样, 使用陈述至less一个好的观点。

这个网站有跨语言的一些很好的例子: http : //jokecamp.wordpress.com/2012/10/21/examples-of-creating-base64-hashes-using-hmac-sha256-in-different-languages/

编写本文时的c#实现是:

 private string CreateToken(string message, string secret) { secret = secret ?? ""; var encoding = new System.Text.ASCIIEncoding(); byte[] keyByte = encoding.GetBytes(secret); byte[] messageBytes = encoding.GetBytes(message); using (var hmacsha256 = new HMACSHA256(keyByte)) { byte[] hashmessage = hmacsha256.ComputeHash(messageBytes); return Convert.ToBase64String(hashmessage); } } 

尝试这个:

http://msdn.microsoft.com/en-us/library/system.security.cryptography.hmacsha1.aspx

快速和肮脏的代码:

 public string Encode(string input, byte [] key) { HMACSHA1 myhmacsha1 = new HMACSHA1(key); byte[] byteArray = Encoding.ASCII.GetBytes( input ); MemoryStream stream = new MemoryStream( byteArray ); byte[] hashValue = myhmacsha1.ComputeHash(stream); return hashValue.ToString(); }