File-Encryption
實施 Inferno 的 ECIES:從發送者的公鑰創建對稱密鑰
我正在編寫(在 C# 中)離線(無網路或伺服器)混合文件加密應用程序,實現 Inferno 的 ECIES。使用者的私鑰在使用經過約 100 萬次 Scrypt 迭代散列的密鑰(密碼)加密後,將儲存在 pc 驅動器或 USB 密鑰上。應用程序啟動後,使用者可以將其密鑰載入到受保護的記憶體中。載入密鑰需要 20 秒的時間,但如果以下情況可以接受,這將是一次/會話延遲:
對於打算由使用者保存的文件(一些被發送,一些被保存),使用使用者自己的公鑰生成“共享”對稱密鑰是否安全?這將允許使用者記住一個密碼(而不是每個對稱和非對稱密鑰一個),並且由於以這種方式生成的對稱密鑰具有高熵,因此在保存/載入文件時不需要散列迭代,這種情況非常經常在會話期間。
程式碼本身正在執行,但這並不能告訴我該方法是否安全。只是為了確保我清楚,這是一個縮短的程式碼範例:
internal static void SendText(string text, byte[] ephemeralPublicBlob, string file) { CngKey receiverKey = ephemeralPublicBlob.ToPublicKeyFromBlob(); var ephemeralBundle = receiverKey.GetSharedEphemeralDhmSecret(); var ephemeralPublic = ephemeralBundle.EphemeralDhmPublicKeyBlob; var ephemeralSymmetric = ephemeralBundle.SharedSecret; var textSegment = new ArraySegment<byte>(text.ToBytes()); var ciphertext = SuiteB.Encrypt(ephemeralSymmetric, textSegment); using (FileStream fs = new FileStream(file, FileMode.Create, FileAccess.Write)) { byte[] sent = Utils.Combine(ephemeralPublic, ciphertext); fs.Write(sent, 0, sent.Length); } } internal static string ReceiveText(string file, CngKey masterKey) { string decrypted = null; using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read)) { byte[] received = new byte[fs.Length]; fs.Read(received, 0, (int)fs.Length); var ephemeralPublic = new ArraySegment<byte>(received, 0, 104); var cipherText = new ArraySegment<byte>(received, 104, received.Length - 104); var sharedSecret = masterKey.GetSharedDhmSecret(ephemeralPublic.ToArray().ToPublicKeyFromBlob()); decrypted = SuiteB.Decrypt(sharedSecret, cipherText).FromBytes(); } return decrypted; }
因此,在第一個函式(SendText)中,如果我將發送者(而不是接收者)的公共 blob 作為字節傳遞
$$ $$論點,程式碼有效,但我是否洩漏/弄亂了一些東西?
你沒有洩露任何東西,因為
ephemeralBundle
它將包含一個新的、唯一的公私臨時密鑰對,並且加密將以全新的方式發生$$ ephemeral_public sender_private == ephemeral_private sender_public $$密鑰。 在上述情況下,使用發送者的 pk 作為接收者(即發送給自己)是安全的。