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

C# Java和C之间的SHA1哈希结果不同#,c#,java,hash,sha1,C#,Java,Hash,Sha1,我有个大问题。 我使用此C#函数对我的消息进行编码: byte[] buffer = Encoding.ASCII.GetBytes(file_or_text); SHA1CryptoServiceProvider cryptoTransformSHA1 = new SHA1CryptoServiceProvider(); String hashText = BitConverter.ToString(cryptoTransformSHA1.ComputeHash(buffer)).Replac

我有个大问题。 我使用此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();

我的信息是:阻止|注释|文本!我猜你似乎在比较ASCII字节和拉丁1字节。尝试切换

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

md.update(text.getBytes("ISO646-US"), 0, text.length());
那可能会解决你的问题

(或开关C#使用拉丁语1)


在您的程序中,您的
GetBytes
方法根据编码为相同的字符返回不同的值,因此我们漂亮的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;
}
公共静态字符串Sha1encode(字符串到加密){
//生成一个字节数组,它是SHA1散列
字节[]SHA1签名=新字节[40];
byte[]sha=System.Text.Encoding.Default.GetBytes(toEncrypt);
SHA1-SHA1=SHA1Managed.Create();
sha1签名=sha1.ComputeHash(sha);
//BASE64编码标准的6位字母表,来自RFC1521,
//加上结尾的填充字符。
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', '+', '/', '=' };
//使用Base64对SHA1哈希进行编码的算法
StringBuilder sb=新的StringBuilder();
int len=sha1签名长度;
int i=0;
国际竞争力;
而(len>=3){
ival=((int)sha1Signature[i++]+256)和0xff;
第12)条和第63)条);
sb.追加(Base64Chars[(ival>>6)和63]);
sb.追加(Base64Chars[ival&63]);
}
开关(透镜){
案例0://不需要pads。
打破
案例1://另外两个输出字节和两个焊盘。
ival=((int)sha1Signature[i++]+256)和0xff;
第18)条和第63)条);
sb.追加(Base64Chars[(ival>>12)和63]);
sb.追加(Base64Chars[64]);
sb.追加(Base64Chars[64]);
打破
案例2://另外三个输出字节和一个pad。
ival=((int)sha1Signature[i++]+256)和0xff;
第12)条和第63)条);
sb.追加(Base64Chars[(ival>>6)和63]);
sb.追加(Base64Chars[64]);
打破
}
字符串base64SHA1签名=sb.ToString();
返回base641签名;
}

为什么在Java代码段中使用iso-8859-1编码,而在C代码段中不使用iso-8859-1编码?在计算哈希之前,字节数组是什么?它们可能不一样(可能是因为您使用ASCII和ISO-8850-1编码),请看一下我可以在C端更改代码吗?在java方面对我来说更难。。。(我无法触及爪哇方面)乔恩·斯基特在他的帖子中解释了这一点。你能说说他是如何造成这种差异的吗?
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;
}