简体   繁体   中英

Can't decrypt video using C# and Rijndael

I can't decrypt a video file that I encrypted it using Rijndael. Have a look at my encryption routine:

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

And this is my decryption routine:

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

Other points: - No error is being thrown but the video is simply not playing. - The size of the decrypted file is the same of the encrypted file.

EDIT :

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

It seems your both methods needs fixes:

1/ encrypt part - you cannot write output data directly to _streamOutput but to _streamCrypto. Otherwise you will write exactly what you have taken from input file. As per your original code, you would encrypt just first block of data.

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

2/ decrypt part - you cannot read from input stream directly but from _streamCrypto

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

3/ PrepareEncryptionKey method should be used in both encryption and decryption method. This will ensure you have it same in both methods.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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