Java SHA256Digest返回一个奇怪的哈希
在BlackBerry应用程序中,我使用以下代码从密码中获取哈希值:Java SHA256Digest返回一个奇怪的哈希,java,blackberry,sha256,Java,Blackberry,Sha256,在BlackBerry应用程序中,我使用以下代码从密码中获取哈希值: SHA256Digest sha256d = new SHA256Digest(); byte[] passwordData = null; try { passwordData = password.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) {
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=ßÝ÷您看到的是二进制形式的散列。必须将其转换为十六进制。这就是问题所在:
tempSHA256Password = new String(hashedValue);
它尝试从任意二进制数据创建字符串,就像它是使用平台默认编码的文本编码一样。听起来你在找hex。Java中有大量不同的十六进制编码实用程序库—您可能需要查看这些库。您不能直接打印二进制值:
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();
}
如果您感兴趣,还可以使用其他示例来说明此方法。而不是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();
StringBuffer=new StringBuffer();
for(字节b:哈希值)
{
buffer.append(String.format(“%02x”),b您能解释一下为什么在Java中使用b字节总是有符号的,但在散列值中字节0xff是255,而不是-1.When(隐式)将字节强制转换为int这段代码将字节值解释为无符号。实际上,这段代码似乎遗漏了两个0(零)。例如,以字符串为例,将其设为字符串。实际的结束十六进制值应为a4ed677da365940d77fff663b7c5e27d9e166514c681df2fa2024089e0bfc422
,但此代码返回的是a4ed677da36594d77fff663b7c5e27d9e166514c681df2fa224089e0bfc422
,可以使用缓冲区轻松修复此问题.append(String.format(“%02x”),bYep,谢谢你的提示。这应该是可行的……但是,在黑莓上不行,因为黑莓没有String.format方法。我想我必须想办法用MessageFormat.format实现这一点……事实上,我正在寻找十六进制字符串。但是,我无法将Apache库导入黑莓项目。似乎我只能使用j2me lBB上的库。我最终使用了。它与您的解决方案类似。事实上,这完全是一样的,您的链接提供了更多的评论。顺便说一句,谢谢!如果您确实想让您的答案适合黑莓操作系统,您应该将StringBuilder
替换为StringBuffer
btw。此外,您还可以删除Base64编码部分,那不是我想做的。