AArnott / PCLCrypto

Platform crypto for portable libraries
Microsoft Public License
229 stars 55 forks source link

extra bytes in transform - adding junk to the decrypted text #31

Closed chriskooken closed 9 years ago

chriskooken commented 9 years ago

We are in the process of gutting a lot of shared functionality in our system and porting it to PCL libraries. I am taking some existing data in our database, and trying to decrypt it with the same algorithm. I get the value back, but there are 16 extra bytes at the end that are just garbage.

See Code below: Old Algorithm using System.Security.Cryptography

public static string SymmetricEncrypt(this string plaintext, string key, SymmetricAlgorithm algorithm)
{
    byte[] keyBuffer = Convert.FromBase64String(key.Hash(HashAlgorithm.MD5));
    byte[] plainTextBuffer = Encoding.UTF8.GetBytes(plaintext);

   var symmetricAlgorithm = new AesCryptoServiceProvider();
    symmetricAlgorithm.Key = keyBuffer;
    symmetricAlgorithm.Mode = CipherMode.ECB;

    var encryptor = symmetricAlgorithm.CreateEncryptor();
    byte[] cipherBuffer = encryptor.TransformFinalBlock(plainTextBuffer, 0, plainTextBuffer.Length);
    symmetricAlgorithm.Clear();

    return Convert.ToBase64String(cipherBuffer);
}

 public static string SymmetricDecrypt(this string cipherText, string key, SymmetricAlgorithm algorithm)
    {
        byte[] keyBuffer = Convert.FromBase64String(key.Hash(HashAlgorithm.MD5));
        byte[] cipherTextBuffer = Convert.FromBase64String(cipherText);
        var symmetricAlgorithm = new AesCryptoServiceProvider();
        symmetricAlgorithm.Key = keyBuffer;
        symmetricAlgorithm.Mode = CipherMode.ECB;

        var decryptor = symmetricAlgorithm.CreateDecryptor();
        byte[] plainTextBuffer = decryptor.TransformFinalBlock(cipherTextBuffer, 0, cipherTextBuffer.Length);
        symmetricAlgorithm.Clear();

        return Encoding.Default.GetString(plainTextBuffer);
    }

Decryption using PCLCrypto

public static string SymmetricDecrypt(this string cipherText, string key, SymmetricAlgorithm algorithm) {
    byte[] keyBuffer = Convert.FromBase64String(key.Hash(HashAlgorithm.MD5));
    byte[] cipherTextBuffer = Convert.FromBase64String(cipherText);

    ISymmetricKeyAlgorithmProvider symmetricAlgorithm = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(PCLCrypto.SymmetricAlgorithm.AesEcb);

    var symmetricKey = symmetricAlgorithm.CreateSymmetricKey(keyBuffer);
    var decryptor = WinRTCrypto.CryptographicEngine.CreateDecryptor(symmetricKey);
   byte[] plainTextBuffer = decryptor.TransformFinalBlock(cipherTextBuffer, 0, cipherTextBuffer.Length);
    return UTF8Encoding.UTF8.GetString(plainTextBuffer, 0, plainTextBuffer.Length);
}

Using the old version: plainTextBuffer is 16 bytes, new version it is 32 bytes.

Help!

AArnott commented 9 years ago

This is because in your desktop decryption code you get the Pkcs7 padding by default, and in PCLCrypto you picked an algorithm with no padding: PCLCrypto.SymmetricAlgorithm.AesEcb. If you instead indicate PCLCrypto.SymmetricAlgorithm.AesEcbPcks7, it works.