SHA哈希函数给出负输出

时间:2011-06-15 11:49:40

标签: java hash sha dsa

我正在尝试实施DSA签名算法而且我遇到了问题。我正在使用java.security MessageDigest类,这是代码:

MessageDigest md;
md = MessageDigest.getInstance("SHA-1");
md.update(text.getBytes());
return new BigInteger(md.digest());

Text是一个随机的String对象。问题是这段代码给出了哈希的负值,这是算法不接受的。难道我做错了什么?提前谢谢。

P.S。顺便说一下,我也试过在不使用BigIntegers的情况下实现DSA,这可能吗?我没有发现L和N值小于1024和160,所以我不知道应该采用什么值以及我应该使用什么哈希函数。非常感谢您听到这些问题的答案。

4 个答案:

答案 0 :(得分:3)

MessageDigest md;
md = MessageDigest.getInstance("SHA-1");
md.update(text.getBytes());
return new BigInteger(1, md.digest()); // use this 1 to tell it is positive.

然后您可以使用:

将哈希值转换为String
String hash = biginteger.toString(16);

然后可选地前置前导零。

String zeros = String.format("%032d", 0);
hash = zeros.substring(hash.length()) + hash;

答案 1 :(得分:2)

你为什么感到惊讶? MessageDigest#digest()返回均匀分布的160位数据。它们通常表示为十六进制字符串,但如果将它们转换为整数,则最高位指定符号。看看这段代码:

System.out.println(new BigInteger(new byte[]{(byte) 255}));  //-1

答案 2 :(得分:1)

您将返回的字节传递给BigInteger constructor。虽然类型匹配,但我不确定你想在这里完成什么。来自BigInteger JavaDoc:

  

转换包含BigInteger的二进制补码二进制表示的字节数组

答案 3 :(得分:0)

不要重新发明轮子,特别是密码术 - 使用java.security.Signature或更高级别的库。