问题是关于在 Java 中创建哈希的正确方法:
假设我有一个积极的BigInteger
我想从中创建哈希的值。让我们假设下面的实例messageDigest
是一个有效的实例(SHA-256)
public static final BigInteger B = new BigInteger("BD0C61512C692C0CB6D041FA01BB152D4916A1E77AF46AE105393011BAF38964DC46A0670DD125B95A981652236F99D9B681CBF87837EC996C6DA04453728610D0C6DDB58B318885D7D82C7F8DEB75CE7BD4FBAA37089E6F9C6059F388838E7A00030B331EB76840910440B1B27AAEAEEB4012B7D7665238A8E3FB004B117B58", 16);
byte[] byteArrayBBigInt = B.toByteArray();
this.printArray(byteArrayBBigInt);
messageDigest.reset();
messageDigest.update(byteArrayBBigInt);
byte[] outputBBigInt = messageDigest.digest();
现在我只假设下面的代码是正确的,因为根据测试,我生成的哈希值与以下生成的哈希值匹配:
http://www.fileformat.info/tool/hash.htm?hex=BD0C61512C692C0CB6D041FA01BB152D4916A1E77AF46AE105393011BAF38964DC46A0670DD125B95A981652236F99D9B681CBF87837EC99 6C6DA04453728610D0C6DDB58B318885D7D82C7F8DEB75CE7BD4FBAA37089E6F9C6059F388838E7A00030B331EB76840910440B1B27AAEAEEB4012B7D7665238A8E3FB0 04B117B58 http://www.fileformat.info/tool/hash.htm?hex=BD0C61512C692C0CB6D041FA01BB152D4916A1E77AF46AE105393011BAF38964DC46A0670DD125B95A981652236F99D9B681CBF87837EC996C6DA04453728610D0C6DDB58B318885D7D82C7F8DEB75CE7BD4FBAA37089E6F9C6059F388838E7A00030B331EB76840910440B1B27AAEAEEB4012B7D7665238A8E3FB004B117B58
但是我不确定我们为什么要执行以下步骤,即
因为在digest()调用之后返回的字节数组是有符号的,并且在这种情况下它是负数,所以我怀疑我们确实需要将其转换为正数,即我们可以使用这样的函数。
public static String byteArrayToHexString(byte[] b) {
String result = "";
for (int i=0; i < b.length; i++) {
result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
}
return result;
}
thus:
String hex = byteArrayToHexString(outputBBigInt)
BigInteger unsignedBigInteger = new BigInteger(hex, 16);
当我构造一个BigInteger
从新的十六进制字符串并将其转换回字节数组,然后我看到符号位(即最重要的位,即最左边的位)设置为 0,这意味着该数字是正数,而且整个字节是从零构造的(00000000)。
我的问题是:是否有任何 RFC 描述了为什么我们需要始终将哈希转换为“正”无符号字节数组。我的意思是,即使摘要调用后生成的数字为负数,它仍然是有效的哈希,对吧?那么为什么我们需要这个额外的程序呢?基本上,我正在寻找一篇论文:标准或 rfc 描述我们需要这样做。