gtamorim
gtamorim

Reputation: 140

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

Upvotes: 1

Views: 840

Answers (1)

Pavel Sem
Pavel Sem

Reputation: 1753

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.

Upvotes: 1

Related Questions