0

BlackBerry应用程序中,我使用此代码从密码中获取哈希:

        SHA256Digest sha256d = new SHA256Digest();
        byte[] passwordData = null;

        try {
            passwordData = password.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        DigestOutputStream outputStream = new DigestOutputStream(sha256d, null);
        try {
            outputStream.write(passwordData);
        } catch (IOException e) {
            e.printStackTrace();
        }

        byte[] hashedValue = sha256d.getDigest();
        tempSHA256Password = new String(hashedValue);
        System.out.println(tempSHA256Password);

在这个代码块的末尾,tempSHA256Password将会是这样的:ëÇ#ÎiGê8óq =ßÝ÷<rê¨_FR»ã......所以绝不是我所期待的。我期待一个看起来像这样的字符串:ebc723ce6947ea38f371a03d0cdfddf73c840f7215eaa85f031446529bbb16e3

我究竟做错了什么?

4

4 回答 4

6

尝试tempSHA256Password = new String(hashedValue); 以下代码:

StringBuffer buffer = new StringBuffer();
for(byte b : hashedValue)
{
    buffer.append(String.format("%02x",b<0 ? b+256 : b));
}
tempSHA256Password = buffer.toString();
于 2012-04-11T09:41:49.237 回答
4

这就是问题:

tempSHA256Password = new String(hashedValue);

它试图从任意二进制数据创建一个字符串,就好像它是使用平台默认编码的文本编码一样。听起来您正在寻找十六进制。Java 中有许多不同的十六进制编码实用程序库——例如,您可能想查看Apache Commons Codec

于 2012-04-11T09:38:44.750 回答
3

您不能直接打印二进制值:

tempSHA256Password = new String(hashedValue);
System.out.println(tempSHA256Password);

因此,如果要将其转换为十六进制,可以使用此方法:

static final String HEXES = "0123456789ABCDEF";
public static String getHex( byte [] raw ) {
  if ( raw == null ) {
    return null;
  }
  final StringBuffer hex = new StringBuffer( 2 * raw.length );
  for ( final byte b : raw ) {
    hex.append(HEXES.charAt((b & 0xF0) >> 4))
     .append(HEXES.charAt((b & 0x0F)));
  }
  return hex.toString();
}

这个方法来自这里,如果你有兴趣,你还有其他的例子。

于 2012-04-11T09:40:39.693 回答
1

你看到的是哈希的二进制形式。您必须将其转换为十六进制。

于 2012-04-11T09:38:31.303 回答