c# - 如何将图像字节数组解密为原始值?

标签 c# encryption

我想加密图片框图像并将其保存到文件中,然后能够对其进行解密并加载回图片框。那里有各种代码示例,但它们似乎都不适合我。我总是得到比原始文件更大的解密文件。

我尝试了不同的方法来做到这一点,这是我写的最新方法:

// 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/

相关文章:

c++ - gcrypt 是针对哪个版本的 PKCS#1 规范实现的?

c# - 有没有 "single line"方式生成加密字符串?

c# - 551 发件人地址对您的登录无效

c# - 我如何使用 Lucene.Net 索引 PDF 文件?

java - 使用网络代理 (nanoHTTPD) 动态传输[随机访问]加密 (AES-CTR) 视频

android - 错误填充异常 : Blocktype mismatch: 0

Java 密码设置特定随机数不起作用

c# - 在C#中更改System.Exception()的错误消息

c# - 具有一组字符而不是一个字符的序列对齐算法

c# - 具有属性的奇怪行为