简体   繁体   English

DES加密解密后无法打开图像C#

[英]cant open the image after decryption of DES encryption C#

I'm having trouble in encrypting and decrypting image with DES encryption 我在使用DES加密对图像进行加密和解密时遇到问题

I'm using the code from http://support.microsoft.com/kb/307010 我正在使用来自http://support.microsoft.com/kb/307010的代码

I modified it a bit(I add the "cryptostream.FlushFinalBlock();" and change the encoding to "Encoding.Default") 我做了一点修改(我添加了“ cryptostream.FlushFinalBlock();”并将编码更改为“ Encoding.Default”)

I tried to encrypt an image and decrypt it but the decrypted image cant be opened(it says "file appears to be damaged or corrupted") 我试图加密图像并对其解密,但是无法打开解密的图像(它说“文件似乎已损坏或损坏”)

the original image size is 18,7 KB(19,159 bytes), the encrypted image is 18,7 KB(19,160 bytes), but the decrypted image is 33,4 KB(34,248 bytes). 原始图像大小为18.7 KB(19,159字节),加密图像为18.7 KB(19,160字节),而解密图像为33.4 KB(34,248字节)。

here is my code 这是我的代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Security;
using System.Security.Cryptography;
using System.Runtime.InteropServices;

namespace microsoft_example
{

public partial class Form1:Form
{
    //
    //  Call this function to remove the key from memory after use for security
    [System.Runtime.InteropServices.DllImport("KERNEL32.DLL", EntryPoint="RtlZeroMemory")]
    public static extern bool ZeroMemory(IntPtr Destination, int Length);

    // Function to Generate a 64 bits Key.
    static string GenerateKey()
    {
        // Create an instance of Symetric Algorithm. Key and IV is generated automatically.
        DESCryptoServiceProvider desCrypto =(DESCryptoServiceProvider)DESCryptoServiceProvider.Create();

        // Use the Automatically generated key for Encryption.
        return Encoding.Default.GetString(desCrypto.Key);
    }

    static void EncryptFile(string sInputFilename, string sOutputFilename, string sKey)
    {
        FileStream fsInput = new FileStream(sInputFilename, FileMode.Open, FileAccess.Read);

        FileStream fsEncrypted = new FileStream(sOutputFilename, FileMode.Create, FileAccess.Write);
        DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
        DES.Key = Encoding.Default.GetBytes(sKey);
        DES.IV = Encoding.Default.GetBytes(sKey);
        ICryptoTransform desencrypt = DES.CreateEncryptor();
        CryptoStream cryptostream = new CryptoStream(fsEncrypted, desencrypt, CryptoStreamMode.Write);

        byte[] bytearrayinput = new byte[fsInput.Length];
        fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
        cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
        cryptostream.FlushFinalBlock();
        cryptostream.Close();
        fsInput.Close();
        fsEncrypted.Close();
    }

    static void DecryptFile(string sInputFilename, string sOutputFilename, string sKey)
    {
        DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
        //A 64 bit key and IV is required for this provider.
        //Set secret key For DES algorithm.
        DES.Key = Encoding.Default.GetBytes(sKey);
        //Set initialization vector.
        DES.IV = Encoding.Default.GetBytes(sKey);

        //Create a file stream to read the encrypted file back.
        FileStream fsread = new FileStream(sInputFilename, FileMode.Open, FileAccess.Read);
        //Create a DES decryptor from the DES instance.
        ICryptoTransform desdecrypt = DES.CreateDecryptor();
        //Create crypto stream set to read and do a
        //DES decryption transform on incoming bytes.
        CryptoStream cryptostreamDecr = new CryptoStream(fsread, desdecrypt, CryptoStreamMode.Read);
        //Print the contents of the decrypted file.
        StreamWriter fsDecrypted = new StreamWriter(sOutputFilename);
        fsDecrypted.Write(new StreamReader(cryptostreamDecr).ReadToEnd());
        fsDecrypted.Flush();
        fsDecrypted.Close();
    }
    //

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender,EventArgs e)
    {
        // Must be 64 bits, 8 bytes.
        // Distribute this key to the user who will decrypt this file.
        string sSecretKey;

        // Get the Key for the file to Encrypt.
        sSecretKey = GenerateKey();

        // For additional security Pin the key.
        GCHandle gch = GCHandle.Alloc( sSecretKey,GCHandleType.Pinned );

        // Encrypt the file.        
        EncryptFile(@"D:\IMAGE\chara\des\aoi2z.jpg", @"D:\IMAGE\chara\des\Encrypted.des", sSecretKey);

        // Decrypt the file.
        DecryptFile(@"D:\IMAGE\chara\des\Encrypted.des", @"D:\IMAGE\chara\des\aoi2zdes.jpg", sSecretKey);

        // Remove the Key from memory. 
        ZeroMemory(gch.AddrOfPinnedObject(), sSecretKey.Length * 2);
        gch.Free();
    }
}
}

I've googled it and it says I should use "FlushFinalBlock" and change the encoding 我已经用谷歌搜索过,它说我应该使用“ FlushFinalBlock”并更改编码

I've tried, still doesnt work 我试过了,还是没用

Thanks before 之前感谢

The problem most likely is the usage of the StreamReader when reading the CryptoStream from the encrypted file. 问题很可能是从加密文件读取CryptoStream时StreamReader的使用。
The StreamReader is good for reading a text-representation of the data, which is visible by the data type returned from .ReadToEnd(); StreamReader非常适合读取数据的文本表示形式,该形式对于从.ReadToEnd();返回的数据类型可见.ReadToEnd(); ( string ). string )。 Now, strings may not be able to parse specific data, especially binary data used in images. 现在,字符串可能无法解析特定数据,尤其是图像中使用的二进制数据。 The most common problem (as far as i have experienced) is that images may contain null-bytes ( \\0 ) which is the termination character for strings. 最常见的问题(据我所知)是图像可能包含空字节( \\0 ),这是字符串的终止字符。
To test if this is the problem, you could check if: 要测试这是否是问题,可以检查是否:
- The file size of the decrypted file is smaller than the original file - If it is smaller, read the bytes of the original file and have a look at the position where the decrypted file ends. -解密文件的文件大小小于原始文件的大小-如果较小,则读取原始文件的字节并查看解密文件结束的位置。 If there is the \\0 -byte, you have the answer. 如果存在\\0字节,则您可以找到答案。

It is possible that the culprit is another special byte sequence and not the \\0 , but that doesn't change the fact that using a StreamReader here isn't the right choice. 罪魁祸首可能是另一个特殊的字节序列,而不是\\0 ,但这并没有改变在这里使用StreamReader不是正确选择的事实。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM