简体   繁体   English

Java SHA1哈希到base64:无符号字节?

[英]Java SHA1 hash to base64 : unsigned bytes?

I am trying to hash a value ( SHA1 ) in both C# and Java , and then return a base64 representation. 我试图在C#Java中 散列值( SHA1 ),然后返回base64表示。 I get 2 different results. 我得到2个不同的结果。

I know this is because Java uses signed bytes while C# doesn't . 我知道这是因为Java使用有符号字节而C# 没有

C# version : C#版本

static public string toSHA1(string toEncrypt)
{
    return toSHA1(toEncrypt, new UTF8Encoding());
}

static public string toSHA1(string toEncrypt, Encoding encoding)
{
    String salt = "fE4wd#u*d9b9kdKszgè02ep5à4qZa!éi6";
    SHA256Managed sha256hasher = new SHA256Managed();
    byte[] hashedDataBytes = sha256hasher.ComputeHash(encoding.GetBytes(toEncrypt + salt));
    return Convert.ToBase64String(hashedDataBytes);
}

Java version : Java版本

public static String toSHA1(String toEncrypt) {
    return toSHA1(toEncrypt, "UTF-8");
}

public static String toSHA1(String toEncrypt, String encoding) {
    String salt = "fE4wd#u*d9b9kdKszgè02ep5à4qZa!éi6";
    String res = null;
    toEncrypt = toEncrypt + salt;
    try {
        byte[] dataBytes = toEncrypt.getBytes(encoding);
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        res = Base64.encodeBytes(md.digest(dataBytes));
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return res;
}

I can't manage to find a solution to get the correct base64 result using Java . 我无法找到使用Java获得正确base64结果的解决方案。

Converting signed values to unsigned ones forces the use of int data type, but as soon as I put it in a byte data type, I get my signed bytes back... 将有符号值转换为无符号值会强制使用int数据类型,但只要我将其放入byte数据类型中,我就会收到带符号的字节...

Base64.encodeBytes is waiting for a byte array, so is there any way I can pass an unsigned byte array to this method ? Base64.encodeBytes正在等待一个byte数组,所以我有没有办法将无符号 byte数组传递给这个方法? What can I do with that int array ? 我该怎么处理这个int数组? :

int[] dataInt = new int[dataBytes.length];
// signed to unsigned
for (int i=0; i<dataBytes.length; i++)
{
    dataInt[i] = (dataBytes[i] & 0xFF);
}

I can't modify the C# version, I have to adapt the Java version to give the same results. 无法修改C#版本,我必须调整Java版本才能得到相同的结果。

The problem is very simple... From your C# code: 问题很简单......来自你的C#代码:

SHA256Managed sha256hasher = new SHA256Managed()

SHA-256 != SHA-1. SHA-256!= SHA-1。 Use the SHA1 class instead in C#, or use SHA-256 in Java as well. 在C#中使用SHA1类,或者在Java中也使用SHA-256。 As you apparently can't change the C# code, you should change the Java instead: 由于您显然无法更改C#代码,因此您应该更改Java:

MessageDigest md = MessageDigest.getInstance("SHA-256");

Once you've done that, the base64-encoded data should be the same in both platforms. 完成后,base64编码的数据应该在两个平台上都相同。 Even though bytes are signed in Java, base64 encoders treat them as unsigned... they're only interested in the bits, basically. 尽管字节是用Java签名的,但base64编码器它们视为无符号......基本上它们只对这些位感兴趣。

I'd also strongly suggest that you represent your salt in ASCII in the source code, using \\uxxxx escaping for any non-ASCII characters. 我还强烈建议您在源代码中用ASCII表示您的salt,使用\\uxxxx转义为任何非ASCII字符。 This will prevent problems due to compiling using the wrong encoding. 这将防止因使用错误编码进行编译而导致的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM