1

我无法解密使用 Rijndael 加密的视频文件。看看我的加密例程:

  using (FileStream _streamInput = new FileStream(inputPath,FileMode.Open,FileAccess.Read)) {
            using (FileStream _streamOutput = new FileStream(outputPath,FileMode.Create,FileAccess.Write)) {
                RijndaelManaged _cryptoRM = new RijndaelManaged();
                UnicodeEncoding _encodingUnicode = new UnicodeEncoding();
                byte[] _key = _encodingUnicode.GetBytes(String.IsNullOrEmpty(customPassword)?_mediaPass:customPassword);
                using (CryptoStream _streamCrypto = new CryptoStream(_streamOutput,
                                                                     _cryptoRM.CreateEncryptor(_key,_key),
                                                                     CryptoStreamMode.Write)) {
                    long _bufferLength = _streamInput.Length;

                    if (_bufferLength>_encryptedBlock) {
                        byte[] _encryptedBuffer        = new byte[_encryptedBlock];
                        byte[] _unencryptedBufferBlock = new byte[_encryptedBlock];

                        // encrypted block
                        _streamInput.Read(_encryptedBuffer,0,(int)_encryptedBlock);
                        _streamCrypto.Write(_encryptedBuffer,0,(int)_encryptedBlock);

                        // rest
                        int _readBytesCount = 0;
                        while ((_readBytesCount=_streamInput.Read(_unencryptedBufferBlock,0,_encryptedBlock))!=0) {
                            _streamOutput.Write(_unencryptedBufferBlock,0,(int)_readBytesCount);
                        }
                    }
                    _streamCrypto.Dispose();
                }
                _cryptoRM.Dispose();
                _streamOutput.Dispose();
            }
            _streamInput.Dispose();
        }

这是我的解密程序:

        using (FileStream _streamInput = new FileStream(inputPath, FileMode.Open, FileAccess.Read))
        {
            using (FileStream _streamOutput = new FileStream(outputPath, FileMode.Create, FileAccess.Write))
            {
                 RijndaelManaged _cryptoRM = new RijndaelManaged();
                 UnicodeEncoding _encodingUnicode = new UnicodeEncoding();
                 byte[] _key = _encodingUnicode.GetBytes(PrepareEncryptionKey(String.IsNullOrEmpty(customPassword)?_mediaPass:customPassword,""));


                try
                {

                        using (CryptoStream _streamCrypto = new CryptoStream(_streamInput, _cryptoRM.CreateDecryptor(_key, _key), CryptoStreamMode.Read))
                        {
                            try
                            {
                                int _readBytesCount = 0;


                                //encrypted block
                                byte[] _buffer = new byte[_encryptedBlock];
                                byte[] _bufferUnencrypted = new byte[_encryptedBlock];

                                int decrypt_length = _streamCrypto.Read(_buffer, 0, _encryptedBlock);                                   
                                _streamOutput.Write(_buffer, 0, decrypt_length);

                                // rest
                                while ((_readBytesCount = _streamInput.Read(_bufferUnencrypted, 0, _encryptedBlock)) != 0)
                                {
                                    _streamOutput.Write(_bufferUnencrypted, 0, _readBytesCount);
                                }
                            }
                            catch { }
                            _streamCrypto.Dispose();
                        }

                }
                catch { }
                _cryptoRM.Dispose();
                _streamOutput.Dispose();
            }
            _streamInput.Dispose();
        }

其他要点: - 没有抛出错误,但视频根本没有播放。- 解密文件的大小与加密文件的大小相同。

编辑

 private static string PrepareEncryptionKey(string key, string part)
    {
        if (part == "")
        {
            if (key.Length != 8)
            {
                return key.PadRight(8, '~');
            }
            else
            {
                return key;
            }
        }
        else
        {
            if (key.Length != (8 - part.Length))
            {
                if (key.Length > (8 - part.Length))
                {
                    return key.Substring(0, (8 - part.Length)) + part;
                }
                else
                {
                    return key.PadRight((8 - part.Length), '~') + part;
                }
            }
            else
            {
                return key + part;
            }
        }
    }
4

1 回答 1

1

看来您的两种方法都需要修复:

1/ 加密部分 - 您不能将输出数据直接写入 _streamOutput 而是写入 _streamCrypto。否则,您将准确地写出您从输入文件中获取的内容。根据您的原始代码,您只需加密第一个数据块。

while ((_readBytesCount = _streamInput.Read(_unencryptedBufferBlock, 0, encryptedBlockSize)) != 0)
{
    _streamCrypto.Write(_unencryptedBufferBlock, 0, (int)_readBytesCount);
}

2/ 解密部分 - 您不能直接从输入流中读取,而是从 _streamCrypto

while ((_readBytesCount = _streamCrypto.Read(_bufferUnencrypted, 0, encryptedBlockSize)) != 0)
{
    _streamOutput.Write(_bufferUnencrypted, 0, _readBytesCount);
}

3/ PrepareEncryptionKey 方法应在加密和解密方法中使用。这将确保您在两种方法中都具有相同的效果。

于 2013-02-14T17:16:55.290 回答