Different SHA1 Hash result between Java and C#

青春壹個敷衍的年華 提交于 2020-01-21 03:44:04

问题


I've a big problem. I using this C# function to encode my message:

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

On java side, I use this snippet:

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

My message is: Block|Notes|Text !£$%&/()=?^€><{}ç°§;:_-.,@#ùàòè+

I have this result:

(C#)   8EDC7F756BCECDB99B045FA3DEA2E36AA0BF0875
(Java) 2a566428826539365bb2fe2197da91395c2b1b72

Can you help me please?? Thanks...


回答1:


My guess is you seem to be comparing ASCII bytes to Latin1 bytes. Try switching

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

to this

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

That might solve your problem.

(Or switch C# to use Latin1)

What is happening in your program your GetBytes method is returning different values for the same characters depending on encoding, so our nifty SHA1 hash algorithm is getting passed different parameters resulting in different return values.




回答2:


The change to use ISO-8859-1 on the C# side is easy:

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

However, both this and ASCII will lose data if your text contains Unicode characters above U+00FF.

Ideally if your source data is genuinely text, you should use an encoding which will cope with anything (e.g. UTF-8) and if your source data is actually binary, you shouldn't be going through text encoding at all.




回答3:


Try the following code:

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;
}


来源:https://stackoverflow.com/questions/3205066/different-sha1-hash-result-between-java-and-c-sharp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!