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

时间:2010-03-30 13:35:02

标签: c# .net encryption cryptography

似乎我的代码在调用加密解密后向结果文件添加了6个字节。 我在mkv文件上尝试.. 请帮忙

这是我的代码

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

4 个答案:

答案 0 :(得分:2)

您的代码不会添加六个字节,3DES会四舍五入到整个块大小。这就是分组密码的工作方式。您将仅在生成的密文中看到此信息,但不会在解密的明文中看到此信息。

再次无需担心,在加密明文之前,分组密码必须将明文填充到下一个块大小。解密密文时,将删除填充。

另外,我做了一个快速的代码审查,你在代码中有错误 - 你使用相同的密钥用于IV和密钥,你真的应该使用不同的数据。所以我会在DecryptFile(),EncryptFile()和SetKeys()中添加另一个arg以允许不​​同的IV。

答案 1 :(得分:0)

我浏览了一下代码并发现没有问题,但我对你使用的类不是很熟悉,所以我可能错了。相反,我会给出一些适用于任何错误的一般建议:

尝试找出问题所在。在许多代码行中很难找到错误。创建显示错误行为的最短代码。

例如,尝试将字符串写入输出流。尺寸是否正确?

  • 如果不是,你几乎找不到问题 - 文件写入有问题,加密内容与问题无关。
  • 如果是,请继续按小步骤添加功能,直到发现问题为止。

这是一种标准的调试技术并且非常有用,我建议每次遇到问题时都使用它。

除此之外,尝试始终保持干净的起始条件,即确保删除写入的文件。在不同的输入上尝试你的代码,看看它是否每次都有完全相同的结果失败,或者是否存在差异。

修改

根据其他回复,64位阻止导致您的麻烦。通过前面介绍的想法,您可以轻松地排除许多其他因素,直到只剩下加密本身。

然后你可以问“为什么TripeDES最多可以为输入添加7个字节?”哪个问题比“我的三重DES包装器有什么问题?”这个问题要清楚得多。 - 你肯定会在不到一分钟的时间内得到这个简单问题的答案!

答案 2 :(得分:0)

Tiple-DES是64位分组密码。如果不分析您的代码,我的猜测是您的数据不是64位对齐的,并且已经使用default PKCS7 mode填充。

答案 3 :(得分:0)

我不知道您使用哪种加密模式,但ECB和CBC模式在最后一个块的末尾添加填充位,以将其大小增加到64位。也许这就是你的字节来自哪里?