2 回答

TA貢獻(xiàn)1806條經(jīng)驗(yàn) 獲得超8個(gè)贊
問題由 Erwin Bolwidt 在評(píng)論中回答:
刪除
digest
是破壞性的,您調(diào)用了兩次 - 您從該方法返回的值不正確
在此之上:
沒有必要調(diào)用
reset()
一個(gè)新的MessageDigest
調(diào)用
update(input)
而不是update(input, 0, input.length)
調(diào)用
digest(input)
而不是update(input)
+digest()
綜合起來,以上所有意味著您的代碼應(yīng)該是:
private static byte[] getSHA1(byte[] input) throws NoSuchAlgorithmException {
return MessageDigest.getInstance("SHA-1").digest(input);
}
測試
byte[] input = "$&).6CXzPHw=2N_+isZK2908069825".getBytes("US-ASCII");
System.out.println(Arrays.toString(getSHA1(input)));
輸出
[-96, -1, 78, 94, -67, -96, -113, 12, -31, 93, -10, -55, -5, 72, -2, -57, 52, -84, -117, 40]
這與Python 輸出相同,除了打印為有符號(hào)字節(jié)和無符號(hào)字節(jié):
[160, 255, 78, 94, 189, 160, 143, 12, 225, 93, 246, 201, 251, 72, 254, 199, 52, 172, 139, 40]

TA貢獻(xiàn)2021條經(jīng)驗(yàn) 獲得超8個(gè)贊
在Java密碼體系結(jié)構(gòu)代表的算法類型,如對象MessageDigest,但也Cipher并Mac全部實(shí)施方案,使得它可以對大量的數(shù)據(jù)進(jìn)行的零碎操作。他們通過更新內(nèi)部狀態(tài)和最終操作的方法來做到這一點(diǎn),例如簽名/驗(yàn)證或 - 對于MessageDigest-digest使用各種重載調(diào)用的單個(gè)操作。
這些算法還有一個(gè)共同點(diǎn),即在調(diào)用“最終”操作時(shí),對象的狀態(tài)會(huì)直接重置為初始化后的狀態(tài)。這種狀態(tài)通常在調(diào)用init方法后達(dá)到。
SHA-1 等哈希算法不需要顯式初始化,因此它們在實(shí)例化后直接返回到狀態(tài):它們尚未處理任何數(shù)據(jù)的狀態(tài)。通過這種方式,可以重用散列算法來散列另一個(gè)值。這比實(shí)例化一個(gè)新對象稍微更有效。
來自JCA 開發(fā)人員指南:
計(jì)算完消息摘要后,消息摘要對象會(huì)自動(dòng)重置并準(zhǔn)備好接收新數(shù)據(jù)并計(jì)算其摘要。所有以前的狀態(tài)(即提供給更新調(diào)用的數(shù)據(jù))都將丟失。
因此,在您調(diào)用該digest()對象后,該對象將重置為尚未收到任何數(shù)據(jù)的狀態(tài)。因此,第二次調(diào)用返回空八位字節(jié)字符串/字節(jié)數(shù)組的哈希值。
所以引用自維基百科:
SHA1("")
gives hexadecimal: da39a3ee5e6b4b0d3255bfef95601890afd80709
這與有符號(hào)字節(jié)相同[-38, 57, -93, -18, 94, 107, 75, 13, 50, 85, -65, -17, -107, 96, 24, -112, -81, -40, 7, 9]:您在注釋中輸入的值。
打印的正確哈希確實(shí)是
A0FF4E5EBDA08F0CE15DF6C9FB48FEC734AC8B28
大寫十六進(jìn)制或
[160, 255, 78, 94, 189, 160, 143, 12, 225, 93, 246, 201, 251, 72, 254, 199, 52, 172, 139, 40]
作為Python 中的無符號(hào)字節(jié)數(shù)組。請注意,Java改為使用有符號(hào)字節(jié),因此這將等于
[-96, -1, 78, 94, -67, -96, -113, 12, -31, 93, -10, -55, -5, 72, -2, -57, 52, -84, -117, 40]
要計(jì)算這個(gè),單個(gè)調(diào)用MessageDigest#digest(byte[] input): byte[]就足夠了,在您的情況下,byte[] digest = msdDigest.digest(input)您可以先打印出來digest 并稍后返回保存字節(jié)數(shù)組的變量。
請注意,仍然不應(yīng)在多個(gè)線程上同時(shí)使用散列;一次只能計(jì)算一個(gè)哈希值;這些類不是線程安全的。
添加回答
舉報(bào)