Aes
c#中靜態數據的AES GCM對稱加密,密文比明文長得多
我已經使用 AES GCM 編寫了加密/解密常式。程式碼可以在這裡找到。
我最近意識到密文比我認為的要長。它應該將標籤和 IV 添加到加密的明文中,但結果仍然比應有的長。
這是進行加密的程式碼部分
using (MemoryStream ms = new MemoryStream()) { using (IAuthenticatedCryptoTransform encryptor = aes.CreateAuthenticatedEncryptor()) { using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) { // Write through and retrieve encrypted data. cs.Write(message, 0, message.Length); cs.FlushFinalBlock(); byte[] cipherText = ms.ToArray(); // Retrieve tag and create array to hold encrypted data. byte[] authenticationTag = encryptor.GetTag(); byte[] encrypted = new byte[cipherText.Length + aes.IV.Length + authenticationTag.Length]; // Set needed data in byte array. aes.IV.CopyTo(encrypted, 0); authenticationTag.CopyTo(encrypted, IV_LENGTH); cipherText.CopyTo(encrypted, IV_LENGTH + TAG_LENGTH); // Store encrypted value in base 64. return Convert.ToBase64String(encrypted); } } }
以下是兩個加密範例:
明文:範例
密文:
XtmTBIqKxKdYKWH2zXRUp8jN6etGNUiTyffAFZYV3KB2WVU=
明文:更長的例子,blah blah blah blah blah
密文:
H17hnG4CSmZQ0UeEcY6wirtjW1il+dw7JHqXwWm908Tvb8/+q0E1HerN0chbuUbhL0jLOs8HIpp7ypQQ/ LTacnWW22CyiwAuiA==
IV 為 12 個字節。我相信身份驗證標籤是 16 個字節。為什麼密文出來的時間比預期的要長得多,我應該如何解決這個問題?謝謝你。
如果您通過數學計算,似乎正在發生預期的密文擴展量。這是正在發生的事情:
- GCM 將明文作為一個大小為 N 的字節串,生成一個密文,它是一個大小為 N+28 的字節串,其中 28 個中的 12 個是 nonce,另外 16 個是認證標籤。
- 然後,該八位字節字元串經過 base-64 編碼,將 3 個字節轉換為 4 個可列印字元;這給出了 4/3 因子的平均密文擴展。
在第一種情況下,您有 7 個字節的明文;加密後,給你一個 35 字節的密文;這 35 個字節的 base-64 編碼預計為 47 個字節長,這正是您所看到的。
在第二種情況下,你有一個 46 字節的明文(假設你給的字元串有一個尾隨空格);加密後,給你一個 74 字節的密文;base-64 編碼是 99 字節,這正是您所看到的。
現在,你問你應該如何解決這個問題。好吧,轉換按設計工作;問題是什麼?如果問題是您擔心某些事情無法正常工作,那麼一切似乎都是正確的。如果問題是密文對您的應用程序來說太長,那麼您需要考慮如何修剪它。這裡有一些簡單的方法:
- 您真的需要輸出可列印嗎?好吧,我看到您在問題上加上了“數據庫”標籤;你在加密數據庫欄位嗎?如果是這樣,數據庫可以儲存任意字節,還是僅限於可列印的字元串?如果它可以儲存任意字節,那麼您可以通過不對文本進行 base-64 編碼來消除很大一部分成本。如果你這樣做了,好吧,如果你很絕望,還有一些更激進的編碼方法(在它們的輸出中使用更多的字元);去其中一個可以為您節省一些錢。