Elliptic-Curves
如何從 ECDH 共享密鑰中導出對稱密鑰?
我正在嘗試實現 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。