簡體   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