Question

I have this peace of code that encrypts stuff using AES, to be more precise Rijndael algorithm to mimic (http://dcx.sybase.com/index.html#sa160/en/dbreference/encrypt-function.html) the behaviour of SQL Anywhere 16, for sake of examples simplicity keys are fake:

var Key = Encoding.ASCII.GetBytes("1234567812345678");
var IV = Encoding.ASCII.GetBytes("1234567812345678");
var text = "stuff";
string encrypted;

var aes = new RijndaelManaged { Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7, BlockSize = 128, KeySize = 128, Key = Key, IV = IV };

using (var encryptor = aes.CreateEncryptor())
{
    var tmp = Encoding.ASCII.GetBytes(text);
    encrypted = Convert.ToBase64String(encryptor.TransformFinalBlock(tmp, 0, tmp.Length));
}
Console.WriteLine("Encrypted text: " + encrypted);

And the result I get: do3BgGEeCWS5+mruUU1Czg== nXnrIX9m4zCxupbPsw3zsg==

Decrypting it in SQL Anywhere 16:

select cast(decrypt(base64_decode('do3BgGEeCWS5+mruUU1Czg=='), '1234567812345678', 'AES(format=RAW;padding=PKCS5)', '1234567812345678') as varchar)

I get this result: s t u f f stuff

So it almost works, comparing in hex it is 0x73007400750066006600 instead of 0x7374756666. Furthermore, if I decrypt same text in C# (decryptor source can be found bellow), I also get same spaces, what am I doing wrong?

Also I tried it other way around, encrypted in SQL Anywhere:

select base64_encode(encrypt('stuff', '1234567812345678', 'AES(format=RAW;padding=PKCS5)', '1234567812345678'))

Got this line: nXnrIX9m4zCxupbPsw3zsg==

Trying to decrypt in C# using same procedure:

string decrypted;

using (var decryptor = aes.CreateDecryptor())
{
    var tmp = System.Convert.FromBase64String(encrypted);
    decrypted = Encoding.ASCII.GetString(decryptor.TransformFinalBlock(tmp, 0, tmp.Length));
};
Console.WriteLine("Decrypted text: " + decrypted);

I get the correct result: stuff with no unnecessary spaces in it.

So it works with a mirror drawback, any ideas where from are those the extra spaces?

Update: Error was in var tmp = Encoding.Unicode.GetBytes(text); line, changed Unicode to ASCII.

Was it helpful?

Solution

If you are using SQL Anywhere version 16.0 or later, you can do this using the 'format=raw' option of the decrypt function. If you are using a version earlier than that, the decrypt function will not be able to decrypt data encrypted outside the database server.

Update: Since you updated your question, I'll address that too. I ran through the decryption in the SQL Anywhere server, and the data that comes out has the embedded NULLs in it, which means that the data that's encrypted already contains the embedded NULLs. I'm not a C# guy so I can't tell you for sure, but I suspect that var text = "stuff"; stores the data in UTF-16.

Full disclosure: I work for SAP in SQL Anywhere engineering.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top