SHA 哈希函数给出负输出

发布于 2024-11-15 22:13:25 字数 441 浏览 4 评论 0原文

我正在尝试实现 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 值,所以我不知道应该采用什么值以及应该使用什么哈希函数。将非常感谢听到这些问题的答案。

I'm trying to implement DSA signature algorithm and I'm stuck on a problem. I'm using the java.security MessageDigest class, here's the code:

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

Text is a random String object. Problem is that this code gives me negative values of hash, which is not accepted by the algorithm. Am I doing something wrong? Thanks in advance.

P.S. By the way, I've also tried to implement DSA without using BigIntegers, is this possible? I've not found the L and N values lesser than 1024 and 160, so I have no idea what values should I take and what hash-function should I use. Will be very thankful to hear the answers on these questions.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

清引 2024-11-22 22:13:25
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;
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.

Then you can convert your hash to a String using:

String hash = biginteger.toString(16);

Then optionally prepend the leading zeros.

String zeros = String.format("%032d", 0);
hash = zeros.substring(hash.length()) + hash;
顾挽 2024-11-22 22:13:25

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

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

Why are you surprised? MessageDigest#digest() returns evenly distributed 160 bits of data. They are typically represented as hexadecimal string, but if you convert them to integer, the most significant bit designates the sign. Check out this code:

System.out.println(new BigInteger(new byte[]{(byte) 255}));  //-1
雪化雨蝶 2024-11-22 22:13:25

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

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

You are passing the bytes returned to the BigInteger constructor. While the types match, I'm not sure what you want to accomplish here. From the BigInteger JavaDoc:

Translates a byte array containing the two's-complement binary representation of a BigInteger

携君以终年 2024-11-22 22:13:25

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

Don't re-invent the wheel, esp for cryptography -- use java.security.Signature or a higher-level library.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文