Encryption

簡單的雙棘輪實現

  • July 19, 2022

這樣的事情是否是實現雙棘輪的合理方法libsodium?我使用的鈉埠非常有限,不提供 kdf。

是關於標量乘法的 libsodium 文件頁面的連結。

什麼crypto_scalarmult_base / crypto_scalarmult是:“在給定使用者的密鑰和另一個使用者的公鑰的情況下計算共享密鑰”。

// random key shared between parties during the initial handshake
const preKey = "yez6GrvuVl3zihPwHf9wiXUv93CSkXHBQhPs6e0YLxg="

// compute the first chain key based on the shared pre key
const chain1 = sodium.crypto_scalarmult_base(preKey)

// compute the actual message key, since chain has just started, 
// use the pre key as the "public key" and chain1 key as 
// the "secret key" for the multiplication
const key1 = sodium.crypto_scalarmult(chain1, preKey)

const cipher1 = encrypt_message(key1)
     
// compute the next chain2 key based on the previous chain1 key
const chain2 = sodium.crypto_scalarmult_base(chain1)

// compute the next message key based on the chain2 key, 
// used as the "secret key" and the chain1 key used as 
// the "public key" for the multiplication
const key2 = sodium.crypto_scalarmult(chain2, chain1)

const cipher2 = encrypt_message(key2)
     
const chain3 = sodium.crypto_scalarmult_base(chain2)
const key3 = sodium.crypto_scalarmult(chain3, chain2)

const cipher3 = encrypt_message(key3)

// and so on ....

據我了解,scalarmult 是不可回溯的,breakkey2不允許你計算key1也不key3

所以我的問題是——這樣的實現是合理的還是完全的災難?

我強烈建議您仔細閱讀整個Point*scalar multiplication頁面和 Signal 的 Double Ratchet文件。您還可以在 Real-World Cryptography 一書中了解雙棘輪和信號協議。

確保您了解 libsodium 函式的作用、Double Ratchet 算法的工作原理以及該算法為何如此設計。

所以我的問題是——這樣的實現是合理的還是完全的災難?

目前尚不清楚它是什麼preKey,但密鑰交換涉及交換兩個公鑰,而不是單個密鑰。如果您交換單個密鑰,則根本不需要使用這樣的非對稱加密。棘手的部分是保持單個密鑰的安全,這就是通常交換公鑰(非秘密)的原因。

crypto_scalarmult_base()從私鑰計算公鑰,而不是共享密鑰。

crypto_scalarmult()計算私鑰和其他人的公鑰的共享密鑰。看起來它被用來從你認為是另一個共享秘密的東西中計算出一個共享秘密;我不完全確定。應該進行不止一次的密鑰交換。

您不應該直接使用共享機密,因為它們不是完全隨機的。它們旨在通過 KDF 傳遞。

此外,對於具有 X25519 的給定公鑰,可以計算幾個等效的公鑰。這可能會導致漏洞,因此建議對與兩個公鑰連接的共享秘密進行散列/KDF。這就是較新的密鑰交換 API 所做的,但我猜你無權訪問它。

我使用的鈉埠非常有限,不提供 kdf。

這是個問題。如果它支持鍵控散列,您可以建構一個 KDF,但聽起來您應該盡可能切換到更好的 libsodium 綁定。

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