File-Encryption

防範針對 MitM 的 ECIES 設置:ECDSA?

  • December 20, 2016

在 ECIES 上下文中對 ETM 文件進行數字簽名是否必要/合適?加密模式為 CTR(使用 Inferno)。目前輸出為:

$$ shared public key $$ $$ ciphertext $$ $$ MAC $$. 加密文件通過電子郵件在使用者之間傳輸,如果重要的話。

使用者需要確保他們收到的消息來自預期的人,並且沒有人願意信任 CA。用 ECDSA 簽署文件有意義嗎?

這是應用程序目前用於加密、解密和身份驗證的程式碼(C#),使用 Inferno(沒有 ECDSA):

   internal static void Encrypt(CngKey k, string file, object data)
   {
       var ephemeralBundle = k.GetSharedEphemeralDhmSecret();
       var ephemeralPublic = ephemeralBundle.EphemeralDhmPublicKeyBlob;
       var symmetricKey = ephemeralBundle.SharedSecret;                                               

       using (var fs = new FileStream(file, FileMode.Create, FileAccess.Write))
       {
           fs.Write(ephemeralPublic, 0, ephemeralPublic.Length);
           using (var etm = new EtM_EncryptTransform(symmetricKey))
           using (var cs = new CryptoStream(fs, etm, CryptoStreamMode.Write))
               new BinaryFormatter().Serialize(cs, data);                                    
       }
   }

   internal static object Decrypt(string file, CngKey k)
   {
       object decrypted = null;
       var ephemeralPublic = new byte[104];

       using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read))
       {
           fs.Read(ephemeralPublic, 0, 104);
           var ephemeralSymmetric = k.GetSharedDhmSecret(ephemeralPublic.ToPublicKeyFromBlob());
           if (Authenticate(file, ephemeralSymmetric, 104))
           {
               using (var etm = new EtM_DecryptTransform(ephemeralSymmetric))
               using (var cs = new CryptoStream(fs, etm, CryptoStreamMode.Read))
                   decrypted = new BinaryFormatter().Deserialize(cs);                    
           }
       }
       return decrypted;
   }

   private static bool Authenticate(string file, byte[] key, int offset)
   {
       using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read))
       using (var etm = new EtM_DecryptTransform(key, authenticateOnly: true))
       {
           fs.Position = offset;
           using (var cs = new CryptoStream(fs, etm, CryptoStreamMode.Read)) cs.CopyTo(Stream.Null);
           if (!etm.IsComplete) throw new Exception("Authentication failed.");
       }
       return true;
   }

是的,如果您想保護消息,您可以使用先簽名後加密或先簽名後加密-再簽名來提供真實性和完整性。沒有它,攻擊者可能會更改密文的位,或者只是創建加密消息。

如果您已經在使用 ECIES,ECDSA 將是合乎邏輯的選擇。不過,使用單獨的密鑰進行簽名和加密可能仍然是一個好主意(如果只是因為您在不同場合需要密鑰)。


不過,在簽名或加密有意義之前,您需要信任對方的公鑰。不信任 CA 是可以的,但在這種情況下,您需要在 PKI 中執行密鑰管理的不同方式。

您可以使用單獨的渠道來確認密鑰指紋,您可以使用信任網路,通過sneakernet(記憶棒)共享密鑰等等。但是如果竊聽是可能的,那麼 10 次中有 9 次也是 MitM,所以你應該確保攻擊者不能用他們自己的公鑰替換公鑰。

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