Java和C#之间的不同SHA1哈希结果

我有一个很大的问题。 我使用这个C#函数来编码我的消息:

byte[] buffer = Encoding.ASCII.GetBytes(file_or_text); SHA1CryptoServiceProvider cryptoTransformSHA1 = new SHA1CryptoServiceProvider(); String hashText = BitConverter.ToString(cryptoTransformSHA1.ComputeHash(buffer)).Replace("-", ""); 

在java方面,我使用这个片段:

 MessageDigest md = MessageDigest.getInstance("SHA-1"); byte[] sha1hash = new byte[40]; md.update(text.getBytes("iso-8859-1"), 0, text.length()); sha1hash = md.digest(); 

我的信息是:Block | Notes | Text!£$%&/()=?^€> <{}ç°§;:_-。,@#ùàòè+

我有这个结果:

 (C#) 8EDC7F756BCECDB99B045FA3DEA2E36AA0BF0875 (Java) 2a566428826539365bb2fe2197da91395c2b1b72 

你能帮我吗?? 谢谢…

我的猜测是你似乎将ASCII字节与Latin1字节进行比较。 尝试切换

 md.update(text.getBytes("iso-8859-1"), 0, text.length()); 

对此

 md.update(text.getBytes("ISO646-US"), 0, text.length()); 

这可能会解决您的问题。

(或者切换C#以使用Latin1)

您的程序中发生的事情GetBytes方法根据编码为相同的字符返回不同的值,因此我们的nifty SHA1哈希算法会传递不同的参数,从而产生不同的返回值。

在C#端使用ISO-8859-1的改变很简单:

 byte[] buffer = Encoding.GetEncoding(28591).GetBytes(file_or_text); 

但是,如果您的文本包含U + 00FF以上的Unicode字符,则此和ASCII都将丢失数据。

理想情况下,如果您的源数据是真正的文本,您应该使用可以处理任何内容的编码(例如UTF-8),如果您的源数据实际上是二进制文件,则根本不应该进行文本编码。

请尝试以下代码:

 public static string Sha1encode(string toEncrypt) { // Produce an array of bytes which is the SHA1 hash byte[] sha1Signature = new byte[40]; byte[] sha = System.Text.Encoding.Default.GetBytes(toEncrypt); SHA1 sha1 = SHA1Managed.Create(); sha1Signature = sha1.ComputeHash(sha); // The BASE64 encoding standard's 6-bit alphabet, from RFC 1521, // plus the padding character at the end. char[] Base64Chars = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '=' }; // Algorithm to encode the SHA1 hash using Base64 StringBuilder sb = new StringBuilder(); int len = sha1Signature.Length; int i = 0; int ival; while (len >= 3) { ival = ((int) sha1Signature[i++] + 256) & 0xff; ival <<= 8; ival += ((int) sha1Signature[i++] + 256) & 0xff; ival <<= 8; ival += ((int) sha1Signature[i++] + 256) & 0xff; len -= 3; sb.Append(Base64Chars[(ival >> 18) & 63]); sb.Append(Base64Chars[(ival >> 12) & 63]); sb.Append(Base64Chars[(ival >> 6) & 63]); sb.Append(Base64Chars[ival & 63]); } switch (len) { case 0: // No pads needed. break; case 1: // Two more output bytes and two pads. ival = ((int) sha1Signature[i++] + 256) & 0xff; ival <<= 16; sb.Append(Base64Chars[(ival >> 18) & 63]); sb.Append(Base64Chars[(ival >> 12) & 63]); sb.Append(Base64Chars[64]); sb.Append(Base64Chars[64]); break; case 2: // Three more output bytes and one pad. ival = ((int) sha1Signature[i++] + 256) & 0xff; ival <<= 8; ival += ((int) sha1Signature[i] + 256) & 0xff; ival <<= 8; sb.Append(Base64Chars[(ival >> 18) & 63]); sb.Append(Base64Chars[(ival >> 12) & 63]); sb.Append(Base64Chars[(ival >> 6) & 63]); sb.Append(Base64Chars[64]); break; } string base64Sha1Signature = sb.ToString(); return base64Sha1Signature; }