我想加密图片框图像并将其保存到文件中,然后能够对其进行解密并加载回图片框。那里有各种代码示例,但它们似乎都不适合我。我总是得到比原始文件更大的解密文件。
我尝试了不同的方法来做到这一点,这是我写的最新方法:
// Save signature file
public void SaveFile(System.Drawing.Image image, string filename, string password)
{
byte[] img = imgToByteArray(image);
byte[] encrypted = Signatures.Encryption.Encrypt(img, password);
File.WriteAllBytes(filename, encrypted);
// DEBUG
byte[] decrypted = Signatures.Encryption.Decrypt(encrypted, password);
image.Save(filename + "O");
File.WriteAllBytes(filename + "E", encrypted);
File.WriteAllBytes(filename + "D", decrypted);
// End of DEBUG
}
// Open signature file
public System.Drawing.Image ReadFile(string filename, string password)
{
byte[] encrypted = File.ReadAllBytes(filename);
byte[] decrypted = Signatures.Encryption.Decrypt(encrypted, password);
Image image = bytearrayToImage(decrypted);
return image;
}
// Convert image to bytearray
private byte[] imgToByteArray(Image img)
{
using (MemoryStream ms = new MemoryStream())
{
img.Save(ms, ImageFormat.Png);
return ms.ToArray();
}
}
// Convert bytearray to image
private Image bytearrayToImage(byte[] bytearray)
{
using (MemoryStream ms = new MemoryStream(bytearray))
{
return Image.FromStream(ms);
}
}
签名.加密:
public static byte[] Encrypt(byte[] input, string password)
{
byte[] output;
PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, new byte[] { 0x43, 0x87, 0x23, 0x72 });
Aes aes = new AesManaged();
aes.Padding = PaddingMode.PKCS7;
aes.KeySize = 256;
aes.Key = pdb.GetBytes(aes.KeySize / 8);
aes.IV = pdb.GetBytes(aes.BlockSize / 8);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(input, 0, input.Length);
}
output = ms.ToArray();
}
return output;
}
public static byte[] Decrypt(byte[] input, string password)
{
byte[] output;
PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, new byte[] { 0x43, 0x87, 0x23, 0x72 });
Aes aes = new AesManaged();
aes.Padding = PaddingMode.PKCS7;
aes.KeySize = 256;
aes.Key = pdb.GetBytes(aes.KeySize / 8);
aes.IV = pdb.GetBytes(aes.BlockSize / 8);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(input, 0, input.Length);
}
output = ms.ToArray();
}
return output;
}
使用 PaddingMode.PKCS7
生成异常:
+ Thrown: "Padding is invalid and cannot be removed." (System.Security.Cryptography.CryptographicException) Exception Message = "Padding is invalid and cannot be removed.", Exception Type = "System.Security.Cryptography.CryptographicException", Exception WinRT Data = null
和PaddingMode.Zeros
生成异常:
+ Thrown: "Parameter is not valid." (System.ArgumentException) Exception Message = "Parameter is not valid.", Exception Type = "System.ArgumentException", Exception WinRT Data = null
我认为 Parameter is not valid.
异常是因为图像无效(因为更高的解密字节长度),CompareBytes(byte[] first, byte [] second)
在所有这些情况下给出 false
。
编辑: I just found out一个 NULL 字节被添加到加密/解密文件的末尾。
EDIT2: NULL 字节在加密时被添加。删除它并没有太大作用,Image.FromStream();
仍然抛出“参数无效。”。
最佳答案
这里的问题是(重新)压缩,而不是加密。我在 JPG 文件上试过你的代码,解密后的输出是 PNG。
要保持大小,您必须在相同的输入上使用相同的编解码器并考虑元数据和数据对齐,即您可能无法控制的东西。
关于c# - 如何将图像字节数组解密为原始值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30590317/