C#简单加密有效,但解密无效?

时间:2019-02-23 20:01:05

标签: c# encryption ecb

希望有人可以提供帮助。我遵循了有关如何制作加密/解密工具的非常简单的教程。加密效果很好,但是解密不起作用。加密的工作原理是,当我在文本文档中打开加密文件时,它都是随机字符,但是当我尝试对其进行解密时,原始数据将无法恢复,只是恢复了更多随机字符。

private void Btn_Encrypt_Click(object sender, EventArgs e)
{
    MessageBox.Show("Your file has been encrypted", "Complete");
    // a simle message box used to notify the user that the encryption process has been completed.
    Encrypt(ShowPathEnc.Text, TxtSaved.Text, key);
    // when the button is clicked the private void "Encrypt" is called and ran.
}

private void Encrypt(string input, string output, string strHash)
{
    FileStream inStream, OutStream;
    // provideds a stearm for the input(selected raw file) to be ran through the encryption algorithm and for the Output(the saved encryption file) for that file to leave 
    //the stearm as an encrypted file
    CryptoStream CryptStream;
    // CryptoStream is used to define a stream that is used to link data streams (inStrean & OutStream) to cryptographyc transformations(ASCII Encoding in this case)
    TripleDESCryptoServiceProvider TripCrypto = new TripleDESCryptoServiceProvider();
    //Defines a wrapper object to access the cryptographic service provider for triple data encryption
    MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider();
    //defines new object that takes a string and uses MD5 to return a 32 character hexedecimal fotrmated string hash. 

    byte[] byteHash, byteText;

    inStream = new FileStream(input, FileMode.Open, FileAccess.Read);
    // takes the raw file that has been selected by the user that is in tne dtream opens that file and reads it.
    OutStream = new FileStream(output, FileMode.OpenOrCreate, FileAccess.Write);
    // takes the save as file that the user has selected opens or creates it and writes the encrypted data into it 
    byteHash = MD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(strHash));
    //  uses the MD5 hash  to compute the data in the file and uses the ASCII key generated earlier to encrypt each byte of data in the file.
    byteText = File.ReadAllBytes(input);
    //reads all the bytes in the in the raw file making to have every byte encrypted.

    MD5.Clear();
    // the hash is then cleared for the next encryption as a completely new unique hash will be used for the next file.

    TripCrypto.Key = byteHash;
    // uses the key to give "TripCrypto" access to the bytes that have been computed by the hash and ASCII encoding.
    TripCrypto.Mode = CipherMode.ECB;
    //sets the triple layer data encryption to use the CBC standard of encryption.

    CryptStream = new CryptoStream(OutStream, TripCrypto.CreateEncryptor(), CryptoStreamMode.Write);
    //uses the cyrptostream to take the file in OutStrean tun it through the Triple layer dadta encryption and the the wtite mode to write the encrypted data back to the 
    //file in the OutStream

    int bytesRead;
    long length, position = 0;
    //instantiates variables used to check the length of the stream in bytes and the position of each byte in the stream
    length = inStream.Length;
    // gets the length of the stream in bytes

    while (position < length)
    {
        bytesRead = inStream.Read(byteText, 0, byteText.Length);
        position += bytesRead;

        CryptStream.Write(byteText, 0, bytesRead);
    }
    //the while loop is comparin g the length of each byte and position of each byte to ensure that there has been a change in position meaning data scrambling
    //is  used aswell as layered encryption.
    inStream.Close();
    OutStream.Close();
    //files have exited bothe streams and therefore there is no need for those streams to be running and they're closed.


}


private void Btn_Decrypt_Click(object sender, EventArgs e)
{
    MessageBox.Show("Your file has been decrypted", "Complete");
    // a simle message box used to notify the user that the encryption process has been completed.
    decrypt(ShowPathDec.Text, SaveDec.Text, key);
    // when the button is clicked the private void "Encrypt" is called and ran.
}
private void decrypt(string input, string output, string strHash)
{
    FileStream inStream, OutStream;
    // provideds a stearm for the input(selected raw file) to be ran through the encryption algorithm and for the Output(the saved encryption file) for that file to leave 
    //the stearm as an encrypted file
    CryptoStream CryptStream;
    // CryptoStream is used to define a stream that is used to link data streams (inStrean & OutStream) to cryptographyc transformations(ASCII Encoding in this case)
    TripleDESCryptoServiceProvider TripCrypto = new TripleDESCryptoServiceProvider();
    //Defines a wrapper object to access the cryptographic service provider for triple data encryption
    MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider();
    //defines new object that takes a string and uses MD5 to return a 32 character hexedecimal fotrmated string hash. 

    byte[] byteHash, byteText;

    inStream = new FileStream(input, FileMode.Open, FileAccess.Read);
    // takes the raw file that has been selected by the user that is in tne dtream opens that file and reads it.
    OutStream = new FileStream(output, FileMode.OpenOrCreate, FileAccess.Write);
    // takes the save as file that the user has selected opens or creates it and writes the encrypted data into it 
    byteHash = MD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(strHash));
    //  uses the MD5 hash  to compute the data in the file and uses the ASCII key generated earlier to encrypt each byte of data in the file.
    byteText = File.ReadAllBytes(input);
    //reads all the bytes in the in the raw file making to have every byte encrypted.

    MD5.Clear();
    // the hash is then cleared for the next encryption as a completely new unique hash will be used for the next file.

    TripCrypto.Key = byteHash;
    // uses the key to give "TripCrypto" access to the bytes that have been computed by the hash and ASCII encoding.
    TripCrypto.Mode = CipherMode.ECB;
    //sets the triple layer data encryption to use the CBC standard of encryption.

    CryptStream = new CryptoStream(OutStream, TripCrypto.CreateDecryptor(), CryptoStreamMode.Write);
    //uses the cyrptostream to take the file in OutStrean tun it through the Triple layer dadta encryption and the the wtite mode to write the encrypted data back to the 
    //file in the OutStream

    int bytesRead;
    long length, position = 0;
    //instantiates variables used to check the length of the stream in bytes and the position of each byte in the stream
    length = inStream.Length;
    // gets the length of the stream in bytes

    while (position < length)
    {
        bytesRead = inStream.Read(byteText, 0, byteText.Length);
        position += bytesRead;

        CryptStream.Write(byteText, 0, bytesRead);
    }
    //the while loop is comparin g the length of each byte and position of each byte to ensure that there has been a change in position meaning data scrambling
    //is  used aswell as layered encryption.
    inStream.Close();
    OutStream.Close();
    //files have exited bothe streams and therefore there is no need for those streams to be running and they're closed.


}

1 个答案:

答案 0 :(得分:1)

简短的答案:在您的CryptoStreams周围放置一个using块。

您正在为加密提供者使用“电子密码簿”模式。 这意味着,除非您为该块提供足够的数据以进行加密,否则它将不会写入加密的块。

我不知道默认的默认块长,但是为了说明起见,我们假装默认为4。

Text before encryption: ABCDEFGHI
[ABCD] -> Fills up the block and gets encrypted.
[DEFG] -> Fills up the block and gets encrypted.
[HI__] -> Doesn't fill up the code block and never gets encrypted or written to your file.

要强制CryptoStream对未完成的块进行加密,可以调用CryptoStream.Flush()或在CryptoStream周围使用using块。