5

我正在尝试实现 DSA 签名算法,但我遇到了一个问题。我正在使用java.security MessageDigest该类,这是代码:

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

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

PS 顺便说一句,我也尝试过不使用 BigIntegers 来实现 DSA,这可能吗?我没有找到小于 1024 和 160 的 L 和 N 值,所以我不知道应该取什么值以及应该使用什么散列函数。将非常感谢听到这些问题的答案。

4

4 回答 4

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 hash = biginteger.toString(16);

然后可选地预先添加前导零。

String zeros = String.format("%032d", 0);
hash = zeros.substring(hash.length()) + hash;
于 2011-06-15T11:56:18.147 回答
3

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

System.out.println(new BigInteger(new byte[]{(byte) 255}));  //-1
于 2011-06-15T11:57:38.537 回答
1

您正在将返回的字节传递给BigInteger 构造函数。虽然类型匹配,但我不确定您想在这里完成什么。来自BigIntegerJavaDoc:

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

于 2011-06-15T11:56:58.043 回答
0

不要重新发明轮子,尤其是密码学——使用java.security.Signature或更高级别的库。

于 2011-06-15T12:03:31.370 回答