所以我正在制作一个从服务器检索图像的程序,该程序在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设置为什么,我们将不胜感激。感谢。
答案 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