解密PKCS#5填充AES / ECB与未知IV

时间:2014-01-17 09:54:36

标签: c# encryption cryptography aes

所以我正在制作一个从服务器检索图像的程序,该程序在AES / ECB中加密并使用PKCS#5填充。我知道用于加密图像的单个同步密钥(M02cnQ51Ji97vwT4),但是,在我用来解密它的代码中,它要求我输入一个IV,我不知道它的值。

以下是我用来解密它的代码:

public static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
    {
        // Check arguments. 
        if (cipherText == null || cipherText.Length <= 0)
            throw new ArgumentNullException("cipherText");
        if (Key == null || Key.Length <= 0)
            throw new ArgumentNullException("Key");
        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException("Key");

        // Declare the string used to hold 
        // the decrypted text. 
        string plaintext = null;

        // Create an RijndaelManaged object 
        // with the specified key and IV. 
        using (RijndaelManaged rijAlg = new RijndaelManaged())
        {
            rijAlg.Key = Key;
            rijAlg.IV = IV;

            // Create a decrytor to perform the stream transform.
            ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);

            // Create the streams used for decryption. 
            using (MemoryStream msDecrypt = new MemoryStream(cipherText))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {

                        // Read the decrypted bytes from the decrypting stream 
                        // and place them in a string.
                        plaintext = srDecrypt.ReadToEnd();
                    }
                }
            }
        }
        return plaintext;
    }

这是我打电话来解密图像的当前代码,然后将其改为我的桌面:

Byte[] lnByte = Encoding.UTF8.GetBytes(General.DecryptStringFromBytes(reader.ReadBytes(1 * 1024 * 1024 * 10), Encoding.UTF8.GetBytes("M02cnQ51Ji97vwT4"), Encoding.UTF8.GetBytes("\0"))); 
                using (FileStream lxFS = new FileStream("C:\\Users\\Admin\\Desktop\\image.jpg", FileMode.Create))
                {
                    lxFS.Write(lnByte, 0, lnByte.Length);
                }

此代码运行时没有任何错误,但是当我打开它保存的图像时,它表示它已损坏或损坏。

现在IV被设置为“\ 0”的原因是因为这是我在网上找到的,但它不起作用。

对于我必须将IV设置为什么,我们将不胜感激。感谢。

2 个答案:

答案 0 :(得分:2)

ECB模式不需要IV。但如果我没弄错的话,RijndaelManaged默认为CBC。因此,您使用的解密方式与用于加密的方式不同。最好不要使用密钥大小,加密模式或填充模式等默认值。

在将加密模式明确设置为ECB并将填充模式设置为PKCS#7填充后再试一次。您不应该为ECB提供IV。

如果您确实需要为实现提供它,那么提供所有零的IV。在CBC模式下,IV与第一个明文块进行异或,因此很容易看出所有零的IV都没有做太多。

如果使用零IV而不是ECB的CBC,那么前16个字节(一个块)将是正确的。之后的所有块都是随机的。大多数情况下,您最后会收到填充错误,但您可能会“幸运”(约为256次)并在结束时获得正确的填充。


此外,您将图像转换为字符编码(字符串)并返回。这将导致数据丢失的大部分时间。相反,您应该将图像视为二进制。

public static void DecryptStringFromBytes(byte[] cipherText, byte[] Key, Stream stream)
{
   // ...

   // Don't use StreamReader

   csDecrypt.CopyTo(stream)

   // ...
}

现在将您生成的FileStream作为最后一个参数提供给该方法。

答案 1 :(得分:0)

ECB模式不需要IV。 CBC模式需要IV,CTR模式需要Nonce。全零IV相当于没有IV。在某些情况下,IV会被添加到密文中,因此您可以尝试将第一个输入块用作其余的IV。

另外,ECB模式并不安全。在维基百科中有一个很好的说明原因:ECB Mode