且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在C#中加密的SQL Anywhere 16中解密AES,反之亦然

更新时间:2023-08-19 18:28:22

如果使用SQL Anywhere 16.0或更高版本,可以使用 解密功能的format = raw'选项。如果您使用的版本早于此,则解密功能将无法解密数据库服务器外加密的数据。



更新:自从你更新了你的问题,我也会解决。我在SQL Anywhere服务器中运行了解密,并且出现的数据中嵌入了NULL,这意味着加密的数据已经包含嵌入的NULL。我不是C#的人,所以我不能确定地告诉你,但我怀疑 var text =stuff; 将数据存储在UTF-16中。 / p>

全面披露:我在SQL Anywhere工程中为SAP工作。


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.

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.