2017-11-11 224 views
1

我正在努力遵循如https://en.wikipedia.org/wiki/SHA-2中所述的SHA-2加密函數。SHA 2哈希和Java的問題

我審查其說行:

  • 開始長度爲L比特的原始消息附加一個單一的「1」位;
  • 附加K'0'位,其中K是最小數量> = 0,使得L + 1 + K +64是512的倍數
  • 將L附加爲64位大端整數,使得總後處理長度是512位的倍數。

我不明白最後兩行。如果我的字符串很短,那麼在添加K'0'位後它的長度是512.我應該如何在Java代碼中實現它?

回答

1

首先,應該清楚地說明所談論的「字符串」不是Java String而是一個位串。這些算法是基於二進制/位的。該實現通常不會處理位而是字節。所以有一個翻譯階段,你應該看到字節而不是位。 (SHA-224/256)或1024位(SHA-384/512)的塊運行SHA-512。所以基本上你有一個64或128字節的緩衝區,你在操作之前就已經加載了。您也可以直接在32位int字段(SHA-224/256)或64位long字段中緩存數據,因爲這是所操作的字大小。

現在填充是比較簡單的程序。填充稱爲位填充。由於它在big-endian模式下使用(SHA-2幸運地使用SHA-3中的braindead little endian模式),填充由一個字節中的最高位設置的單個位組成,其餘部分由零。這使得必須放入緩衝區的值爲(byte) 0x80

如果由於緩衝區已滿而無法創建此填充,則必須處理先前的塊,然後將現有可用緩衝區的第一位設置爲(byte) 0x80。在較新的Java中,您還可以使用(byte) 0b1_0000000字節,這更明確。

現在,您只需添加零即可,直到剩餘8到16個字節,這取決於所使用的散列輸出大小。如果沒有足夠的字節,則填充直到結束,處理該塊,然後重新開始填充零字節,直到再次有8或16個字節。

現在最後你必須編碼的數字,用你剩下的8或16個字節。因此,請將您的輸入乘以8,並確保按照您所期望的Java中最低有效位儘可能多的方式對這些字節進行編碼。如果您不想自己編程,可能需要使用https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html#putLong-long-。無論如何,你可能會忘記超過2^56字節的任何內容,所以如果你有SHA-384/SHA-512,那麼簡單地將前八個字節設置爲零。

就是這樣,除了您仍然需要處理最後一個塊,然後根據您的特定輸出大小,從左側使用盡可能多的字節。

+0

請注意,Bouncy Castle和Java源代碼都可用。有時他們不太容易閱讀,所以我一直很好,並描述它。 –