简体   繁体   English

我的三重 DES 包装器有什么问题?

[英]Whats wrong with my triple DES wrapper?

it seems that my code adds 6 bytes to the result file after encrypt decrypt is called.. i tries it on a mkv file.. please help似乎我的代码在调用加密解密后向结果文件添加了 6 个字节..我在 mkv 文件上尝试.. 请帮忙

here is my code这是我的代码

class TripleDESCryptoService : IEncryptor, IDecryptor
{
    public void Encrypt(string inputFileName, string outputFileName, string key)
    {
        EncryptFile(inputFileName, outputFileName, key);
    }

    public void Decrypt(string inputFileName, string outputFileName, string key)
    {
        DecryptFile(inputFileName, outputFileName, key);
    }

    static void EncryptFile(string inputFileName, string outputFileName, string sKey)
    {
        var outFile = new FileStream(outputFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);

        // The chryptographic service provider we're going to use
        var cryptoAlgorithm = new TripleDESCryptoServiceProvider();
        SetKeys(cryptoAlgorithm, sKey);

        // This object links data streams to cryptographic values
        var cryptoStream = new CryptoStream(outFile, cryptoAlgorithm.CreateEncryptor(), CryptoStreamMode.Write);

        // This stream writer will write the new file
        var encryptionStream = new BinaryWriter(cryptoStream);

        // This stream reader will read the file to encrypt
        var inFile = new FileStream(inputFileName, FileMode.Open, FileAccess.Read);
        var readwe = new BinaryReader(inFile);

        // Loop through the file to encrypt, line by line
        var date = readwe.ReadBytes((int)readwe.BaseStream.Length);


        // Write to the encryption stream
        encryptionStream.Write(date);


        // Wrap things up
        inFile.Close();
        encryptionStream.Flush();
        encryptionStream.Close();
    }

    private static void SetKeys(SymmetricAlgorithm algorithm, string key)
    {
        var keyAsBytes = Encoding.ASCII.GetBytes(key);
        algorithm.IV = keyAsBytes.Take(algorithm.IV.Length).ToArray();
        algorithm.Key = keyAsBytes.Take(algorithm.Key.Length).ToArray();
    }

    static void DecryptFile(string inputFilename, string outputFilename, string sKey)
    {
        // The encrypted file
        var inFile = File.OpenRead(inputFilename);

        // The decrypted file
        var outFile = new FileStream(outputFilename, FileMode.OpenOrCreate, FileAccess.ReadWrite);

        // Prepare the encryption algorithm and read the key from the key file
        var cryptAlgorithm = new TripleDESCryptoServiceProvider();

        SetKeys(cryptAlgorithm, sKey);

        // The cryptographic stream takes in the encrypted file
        var encryptionStream = new CryptoStream(inFile, cryptAlgorithm.CreateDecryptor(), CryptoStreamMode.Read);

        // Write the new unecrypted file
        var cleanStreamReader = new BinaryReader(encryptionStream);
        var cleanStreamWriter = new BinaryWriter(outFile);
        cleanStreamWriter.Write(cleanStreamReader.ReadBytes((int)inFile.Length));
        cleanStreamWriter.Close();
        outFile.Close();
        cleanStreamReader.Close();
    }
}

Your code is not adding six bytes, 3DES is rounding up to a full block size.您的代码没有添加六个字节,3DES 将四舍五入为完整的块大小。 This is how block ciphers work.这就是分组密码的工作原理。 You will see this only in the resulting ciphertext, but not in the decrypted plaintext.您只会在生成的密文中看到这一点,而不会在解密的明文中看到。

Again there is no need to worry, block ciphers must pad your plaintext to the next block size before it can encrypt the plaintext.再次不必担心,块密码必须将您的明文填充到下一个块大小,然后才能加密明文。 When you decrypt the ciphertext, the padding is removed.当您解密密文时,填充被删除。

Also, I did a quick code review, and you have an error in the code - you are using the same key for the IV and the key, and you really should use different data.另外,我做了一个快速的代码审查,你在代码中有一个错误——你对 IV 和密钥使用了相同的密钥,你真的应该使用不同的数据。 So I would add another arg to DecryptFile(), EncryptFile() and SetKeys() to allow for a different IV.所以我会向 DecryptFile()、EncryptFile() 和 SetKeys() 添加另一个 arg 以允许不同的 IV。

I glanced over the code and found no problem, but I'm not very familiar with the classes you used so I may well be wrong.我看了一眼代码,发现没有问题,但我对你使用的类不是很熟悉,所以我很可能是错的。 Instead, I'll give some general advice that applies to any bug:相反,我将给出一些适用于任何错误的一般建议:

Try to hunt down the problem.尝试追捕问题。 It's difficult to find a mistake in many lines of code.在多行代码中很难找到错误。 Create the shortest possible code that displays the faulty behavior.创建显示错误行为的尽可能短的代码。

For instance, try to write a string to the output stream.例如,尝试将字符串写入输出流。 Is the size correct?尺寸是否正确?

  • If no, you almost found the problem - something is wrong with file writing, the encryption stuff has nothing to do with the issue.如果没有,您几乎发现了问题 - 文件写入有问题,加密内容与问题无关。
  • If yes, continue to add functionality in small steps until you discover the problem.如果是,请继续小步添加功能,直到发现问题。

That's a standard debugging technique and extremely helpful, I suggest to use it every time you encounter a problem.这是一种标准的调试技术并且非常有用,我建议您每次遇到问题时都使用它。

Aside from that, try to always have clean starting conditions, ie make sure the file written to was deleted.除此之外,尝试始终保持干净的启动条件,即确保写入的文件已被删除。 Try your code on different input and see if it fails with the exact same result every time or if there are differences.在不同的输入上尝试您的代码,看看它是否每次都以完全相同的结果失败或者是否存在差异。

Edit:编辑:

According to other responses, the 64 bit block is causing your trouble.根据其他回复,64 位块给您带来了麻烦。 With the ideas described earlier, you can easily exclude many other factors until only the encryption itself would be left.使用前面描述的想法,您可以轻松排除许多其他因素,直到只剩下加密本身。

Then you're able to ask "Why is TripeDES adding up to 7 bytes to the input?"然后你就可以问“为什么 TripeDES 为输入增加了多达 7 个字节?” which would a far more clear question than "What's wrong with my triple DES wrapper??"这比“我的三重 DES 包装器有什么问题?”要清楚得多。 - and you would have gotten an answer to this simple question in less than a minute for sure! - 你肯定会在不到一分钟的时间内得到这个简单问题的答案!

Tiple-DES is a 64 bit block cipher. Tiple-DES 是一种 64 位分组密码。 Without analyzing your code my guess is that your data isn't 64-bit aligned and that it has been padded with the default PKCS7 mode .在不分析您的代码的情况下,我的猜测是您的数据不是 64 位对齐的,并且已使用默认的 PKCS7 mode进行填充。

I don't know which encryption mode you use, but ECB and CBC mode add padding bits at the end of the last block to increase it's size to 64 bit.我不知道您使用哪种加密模式,但 ECB 和 CBC 模式在最后一个块的末尾添加填充位以将其大小增加到 64 位。 Maybe that's where your bytes come from?也许这就是您的字节的来源?

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

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