Elliptic-Curves

如何從 ECDH 共享密鑰中導出對稱密鑰?

  • December 3, 2020

我正在嘗試實現 ECDH 的內部原語。目前,我能夠將接收者的公共 EC 點與發送者的私鑰相乘以到達共享的 EC 點。下一步是將作為大數的共享點的 x 座標輸入到散列函式。曲線是 secp521r1,所以共享的 x 座標大小為 66 字節。

問題 1

在散列之前必須將 x 座標 bignum 轉換為什麼格式?對方是openssl。

像下面這樣的東西是否足夠…

...
print_hex(hash_input_buffer, shared_x_coordinate_bignum_bytes, 66);
...

void print_hex(unsigned char* to, unsigned char* from, int len)
{
   for (int i = 0; i < len; ++i)
   {
       sprintf((char*)to + (i * 2), "%02x", from[i]);
   }
}

或者

sprintf(hash_input_buffer, "%64x", shared_x_coordinate_bignum_bytes);

問題2

如果散列函式是 SHA-512 並且我想從中派生一個 AES-256 密鑰,我應該只取 64 字節散列輸出的前 32 個字節嗎?

從(臨時)Diffie-Hellman 密鑰協議派生密鑰的一般想法是使用 KBKDF - 基於密鑰的密鑰派生函式。KBKDF 在遵守哪些安全要求方面大多沒有明確定義。幸運的是,創建 KBKDF 並不難。使用加密安全的散列通常會讓你走得很遠。但是,您應該注意,在這種情況下,雜湊不應容易受到定時和其他側通道攻擊。

KBKDF 或雜湊的輸入是位。通常,儘管只有字節用作輸入。所以你應該直接使用共享密鑰的 66 字節。您轉換為十六進制可能已經洩漏了側通道(時序)資訊。所以第一個問題的答案是:根本不轉換x座標

您確實可以將 SHA-512 雜湊的任何部分作為密鑰。然而,在加密社區中,獲取結果雜湊值的第一個 - 最左邊 - 字節是更標準的。所以這應該回答問題 2:就像你已經在做的那樣使用最左邊的字節

如果您想符合標準並使用 KBKDF,請查看HKDF

引用自:https://crypto.stackexchange.com/questions/28930