Search code examples
c#cryptographyaesbouncycastle

Convert encryption from AesCryptoServiceProvider to BouncyCastle


I have file on disk encrypted with AesCryptoServiceProvider. I need to convert the code to PCL (which doesn't have the class AesCryptoServiceProvider). So i would like to use Bouncy Castle ( https://www.nuget.org/packages/Portable.BouncyCastle/ ) to read and save files without changing the encryption. And prevent the need to convert all the files..

Key is 32 bytes long. IV is 16 bytes long.

Here is the original code :

private static byte[] Encrypt(string plainText, byte[] Key, byte[] IV)
{
    using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
    {
        aesAlg.Key = Key;
        aesAlg.IV = IV;

        ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
        using (MemoryStream outputStream = new MemoryStream())
        {
            using (CryptoStream csEncrypt = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write))
            {
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                {
                    swEncrypt.Write(plainText);
                }
            }

            return outputStream.ToArray();
        }
    }
}

The default mode of AesCryptoServiceProvider is CBC with a padding of type PKCS7, then i tried with classes CbcBlockCipher and Pkcs7Padding. Here is my last try :

private static byte[] Encrypt(byte[] input, byte[] key, byte[] IV)
{
    var keyParameter = new KeyParameter(key);
    var parameters = new ParametersWithIV(keyParameter, IV);

    var cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(new AesEngine()), new Pkcs7Padding());

    cipher.Init(true, parameters);

    var rsl = new byte[cipher.GetOutputSize(input.Length)];
    var outOff = cipher.ProcessBytes(input, 0, input.Length, rsl, 0);

    cipher.DoFinal(rsl, outOff);
    return rsl;
}

The original result for text "test" is 8jykPv2OSILKjJwvgLRr1w==, but with new code is BaYeiuWSnRiHXBpwt19Dag== .

Then what i miss?

Thanks for your help!

Update #1 : Here is the value for Key and IV :

private static byte[] KEY = {98, 193, 95, 78, 211, 151, 118, 57, 179, 5, 85, 181, 133, 20, 94, 101, 184, 175, 94, 164, 150, 119, 75, 207, 189, 178, 21, 213, 13, 217, 174, 44};
private static byte[] IV = {1, 199, 179, 189, 160, 220, 229, 238, 179, 14, 255, 147, 187, 49, 179, 134 };

Update #2 : For Bouncy Castle, I convert my plainText to input with this line :

var input = Encoding.Unicode.GetBytes(plainText);

The difference come from there...


Solution

  • Before calling the Encrypt() method using BouncyCastle, I converted my string with Encoding.Unicode.GetBytes(plainText); instead of Encoding.UTF8.GetBytes(plainText);

    With this fix, both method give the same result!