簡體   English   中英

RSA 加密,長度變差

[英]RSA Encryption, getting bad length

撥打以下 function 時:

byte[] bytes = rsa.Encrypt(System.Text.UTF8Encoding.UTF8.GetBytes(stringToEncrypt), true);

我現在收到錯誤:長度錯誤。

使用較小的字符串它可以工作,任何想法可能是我傳遞的字符串的問題都在 200 個字符以下。

RSA 加密僅適用於少量數據,您可以加密的數據量取決於您使用的密鑰的大小,例如對於 1024 位 RSA 密鑰和 PKCS #1 V1.5 填充,您可以加密最多117個字節,用2048個RSA密鑰,可以加密245個字節。

這有一個很好的理由,非對稱加密在計算上很昂貴。 如果要加密大量數據,則應使用對稱加密。 但是如果你想要不可否認性呢? 那么你要做的就是同時使用兩者。 您創建一個對稱密鑰並使用非對稱加密來交換它,然后安全地交換對稱密鑰來加密您的大量數據。 這就是 SSL 和 WS-Secure 在幕后使用的內容。

對於未來關於 RSA 錯誤長度異常的搜索......

您可以計算可以使用特定密鑰大小加密的最大字節數,如下所示:

((KeySize - 384) / 8) + 37

但是,如果最佳非對稱加密填充 (OAEP) 參數為真,如原始帖子中所述,則可以使用以下內容來計算最大字節數:

((KeySize - 384) / 8) + 7

合法的密鑰大小為 384 到 16384,跳過大小為 8。

如上所述,“錯誤長度”類型異常的解決方案是混合使用對稱和非對稱加密,以便您加密的文本大小不受密鑰大小的限制。 您基本上使用 RSA 加密對隨機密鑰進行非對稱加密。

對於加密:

  1. 生成對稱加密技術(例如 AES 或 Rijndael)所需長度的隨機密鑰。

  2. 使用步驟 1 中生成的隨機密鑰,使用 AES/Rijndael 對稱加密您的文本/數據。

  3. 使用 RSA,對步驟 1 中生成的隨機密鑰進行非對稱加密。

對於解密:

  1. 首先使用您的私有 RSA 密鑰解密 AES/Rijndael 生成的隨機密鑰。

  2. 然后使用 RSA 解密的隨機密鑰解密原始文本/數據

為了演示,您可能希望在 C# 中查看以下示例:

http://www.technical-recipes.com/2013/using-rsa-to-encrypt-large-data-files-in-c/

我在對少於 200 個字符的純文本進行 2048 RSA 加密時遇到了同樣的挑戰。

在我看來,我們可以在不涉及對稱或非對稱加密的復雜性的情況下,通過以下簡單的步驟來實現目標;

通過這樣做,我設法加密和解密了 40 倍大的文本

加密:

  1. 使用 *Zip() 方法壓縮純文本並轉換為字節數組
  2. 使用 RSA 加密

解密:

  1. 使用 RSA 解密密碼文本
  2. 使用 **Unzip() 方法解壓縮解密數據

*byte[] bytes = Zip(stringToEncrypt); // Zip() 方法復制到下面

**decryptedData = Unzip(decryptedBytes); // Unzip() 方法復制到下面


public static byte[] Zip(string str)
{
    var bytes = System.Text.Encoding.UTF8.GetBytes(str);    
    using (var msi = new MemoryStream(bytes))
    using (var mso = new MemoryStream())
    {
        using (var gs = new GZipStream(mso, CompressionMode.Compress))
        {                        
            CopyTo(msi, gs);
        }    
        return mso.ToArray();
    }
}
public static string Unzip(byte[] bytes)
{
    using (var msi = new MemoryStream(bytes))
    using (var mso = new MemoryStream())
    {
        using (var gs = new GZipStream(msi, CompressionMode.Decompress))
        {                     
            CopyTo(gs, mso);
        }    
        return System.Text.Encoding.UTF8.GetString(mso.ToArray());
    }
}

public static void CopyTo(Stream src, Stream dest)
    {
        byte[] bytes = new byte[4096];

        int cnt;

        while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0)
        {
            dest.Write(bytes, 0, cnt);
        }
    }
// [keySize] ÷ 8 - [11 bytes for padding] = Result
// Exsimple: [2048 key size] ÷ 8 - [11 bytes for padding] = 245
public static int GetSizeOutputEncryptOfKeySize(System.Security.Cryptography.RSA rsa) => (rsa.KeySize / 8) - 11;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM