繁体   English   中英

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

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

我在使用DES加密对图像进行加密和解密时遇到问题

我正在使用来自http://support.microsoft.com/kb/307010的代码

我做了一点修改(我添加了“ cryptostream.FlushFinalBlock();”并将编码更改为“ Encoding.Default”)

我试图加密图像并对其解密,但是无法打开解密的图像(它说“文件似乎已损坏或损坏”)

原始图像大小为18.7 KB(19,159字节),加密图像为18.7 KB(19,160字节),而解密图像为33.4 KB(34,248字节)。

这是我的代码

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();
    }
}
}

我已经用谷歌搜索过,它说我应该使用“ FlushFinalBlock”并更改编码

我试过了,还是没用

之前感谢

问题很可能是从加密文件读取CryptoStream时StreamReader的使用。
StreamReader非常适合读取数据的文本表示形式,该形式对于从.ReadToEnd();返回的数据类型可见.ReadToEnd(); string )。 现在,字符串可能无法解析特定数据,尤其是图像中使用的二进制数据。 最常见的问题(据我所知)是图像可能包含空字节( \\0 ),这是字符串的终止字符。
要测试这是否是问题,可以检查是否:
-解密文件的文件大小小于原始文件的大小-如果较小,则读取原始文件的字节并查看解密文件结束的位置。 如果存在\\0字节,则您可以找到答案。

罪魁祸首可能是另一个特殊的字节序列,而不是\\0 ,但这并没有改变在这里使用StreamReader不是正确选择的事实。

暂无
暂无

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

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