This project is read-only.

CryptoStream throws 'The input data is not a complete block'

Nov 7, 2014 at 8:30 AM
Edited Nov 7, 2014 at 8:32 AM
Hi,

I'm trying to get in touch with PCLCrypto by doing some basic symmetric encryption operations. My enryption code looks like this:
public static byte[] encrypt(byte[] data, ICryptographicKey key)
{
    byte[] encrypted;

    ICryptoTransform encryptor = WinRTCrypto.CryptographicEngine.CreateEncryptor(key);
            
    using (MemoryStream msEncrypt = new MemoryStream())
    {
        using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
        {
            csEncrypt.Write(data, 0, data.Length);
        }
        encrypted = msEncrypt.ToArray();
    }

    return encrypted;
}
Calling this method with:
byte[] plaintext = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };            
string password = "123456789";
byte[] salt = { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90 };
int iterations = 500;
int keyLengthInBytes = 32;
byte[] derivedKey = NetFxCrypto.DeriveBytes.GetBytes(password, salt, iterations, keyLengthInBytes);

var algo = PCLCrypto.SymmetricAlgorithm.AesCbc;
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(algo);
ICryptographicKey key = provider.CreateSymmetricKey(derivedKey);

byte[] encrypted = AES_PCLCrypto.encrypt(plaintext, key);
I'm getting a CryptographicException 'The input data is not a complete block'.
Stacktrace looks like this:
System.Security.Cryptography.CapiSymmetricAlgorithm.PadBlock(Byte[] block, Int32 offset, Int32 count)
System.Security.Cryptography.CapiSymmetricAlgorithm.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
PCLCrypto.SymmetricCryptographicKey.CryptoTransformAdaptor.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
PCLCrypto.CryptoStream.FlushFinalBlock()
PCLCrypto.CryptoStream.Dispose(Boolean disposing)
System.IO.Stream.Close()
System.IO.Stream.Dispose()
AESTest.AES_PCLCrypto.encrypt(Byte[] data, ICryptographicKey key) in AES_PCLCrypto.cs:Zeile 45.
AESTest.Program.Main(String[] args) in Program.cs:Zeile 68.
System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
System.Threading.ThreadHelper.ThreadStart_Context(Object state)
System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
System.Threading.ThreadHelper.ThreadStart()
So the Exception is thrown when closing the CryptoStream, but I can't figure out the problem.
Not sure if I'm missing something? I appreciate any help or suggestions!

Thanks!
Nov 7, 2014 at 3:35 PM
Yes, you're missing padding. Your input length isn't exactly the right length for the cipher block you're using, so you have to apply padding either manually by increasing the length of your input buffer or by adding padding to your algorithm:
var algo = PCLCrypto.SymmetricAlgorithm.AesCbcPkcs7;
Marked as answer by thoffm on 1/13/2015 at 12:35 AM
Nov 10, 2014 at 7:46 AM
Thank you! That did the trick!