PGP 字元串到鍵說明符
我一直在閱讀 PGP 標準,在這裡我有點困惑。本節討論將字元串數據轉換為會話密鑰。我對粗體的段落感到困惑。首先,“雜湊上下文”是什麼意思?其次,它指的是哪些“數據”?那段是否還在談論如果雜湊太小該怎麼辦?
簡單的 S2K
這直接對字元串進行雜湊處理以產生關鍵數據。請參閱下文了解如何完成此雜湊。
Octet 0: 0x00 Octet 1: hash algorithm
簡單的 S2K 對密碼進行散列以生成會話密鑰。完成此操作的
方式取決於會話密鑰的大小
(取決於所使用的密碼)和散列算法輸出的大小。
如果散列大小大於會話密鑰大小,則將散列的高位(最左邊)八位字節用作密鑰。
如果散列大小小於密鑰大小,則會創建多個散列上下文實例——足以產生所需的密鑰數據。這些實例預載入了 0, 1, 2, … 八位字節的零(也就是說,第一個實例沒有預載入,第二個實例預載入了 1 個八位字節的零,第三個預載入了兩個八位字節的零,等等)。
當數據被散列時,它被獨立地提供給每個散列上下文。由於上下文的初始化方式不同,它們將各自產生不同的雜湊輸出。一旦密碼被散列,來自多個散列的輸出數據被連接起來,最左邊的第一個散列,以產生關鍵數據,右側的任何多餘的八位字節被丟棄。
是的,它仍然在討論需要多個雜湊才能達到密鑰大小的情況。這樣的功能稱為鍵擴展功能。
它解釋了它們在密碼(數據)上是獨立的(不同的上下文)。不同的上下文意味著對散列函式的呼叫不互動; $ H $ 被視為對完整雜湊函式的一次呼叫。
例如,使用 160 位散列(例如 SHA-1)和 256 位密鑰,您可以連接 $ H(p)||H(0x00||p) $ ,然後取最左邊的 256 位(即丟棄最右邊的 8 個八位字節)。
如果你需要第三個雜湊塊,那就是 $ H(0x00||0x00||p) $ , ETC。
並不是真的不同意,而是更具體地了解上下文:
一般來說,加密散列(以及其他散列)和對稱密碼有時需要處理太大的數據,無法方便地放入單個緩衝區或放入記憶體中(尤其是在小型或嵌入式系統上)。因此,它們通常以這樣一種方式編碼,其中一個常式(函式、方法等)呼叫設置初始狀態,另一個處理一大塊數據,如果有多個數據塊,則可以多次執行,以及一個“最終”或“完成”或“完成”常式產生結果(用於散列)或完成和/或驗證數據(塊密碼模式的填充,認證密碼模式的認證標籤,可能還有其他)。內部狀態需要從一個常式呼叫傳遞到下一個常式呼叫稱為上下文。
例如,在 OpenSSL to MD5 中,您可以:
- 聲明一個類型的變數
MD5_CTX
(或malloc
該大小的空間)MD5_Init
用上下文的地址呼叫- 呼叫
MD5_Update
上下文的地址,以及一些數據的地址和長度- 如果有多個數據緩衝區,則
MD5_Update
根據需要再次呼叫- 呼叫
MD5_Final
上下文的地址,以及儲存雜湊值的地址和長度- “釋放”(或
free
)上下文空間對於 S2K,被散列的數據足夠小,很容易直接計算每個散列輸入和輸出,就像在@otus 答案中一樣。RFC4880中的描述允許您“啟動”所有需要的雜湊,然後將(密碼)數據執行到所有雜湊中,然後連接輸出。這有點矯枉過正,但由於 RFC 的目的是允許不同的實現互操作,所以他們小心不要過度指定實現。