admin

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

sql

我有这种使用AES加密内容的代码,可以更精确地模仿Rijndael算法(http://dcx.sybase.com/index.html#sa160/en/dbreference/encrypt-
function.html)的行为为了示例,SQL Anywhere 16简化键是伪造的:

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);

结果是: do3BgGEeCWS5 + mruUU1Czg == nXnrIX9m4zCxupbPsw3zsg ==

在SQL Anywhere 16中解密它:

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

我得到这个结果: 东西 东西

所以 几乎 作品, 以十六进制比较它是0x73007400750066006600而不是0x7374756666
。此外,如果我在C#中解密相同的文本(可以在下面找到解密器源), 我也得到相同的空格,我在做什么错?

我也尝试了其他方法,在SQL Anywhere中进行了加密:

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

得到了这一行: nXnrIX9m4zCxupbPsw3zsg ==

尝试使用相同的步骤在C#中解密:

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);

:我得到正确的结果 的东西 ,在它没有多余的空格。

因此它具有镜面缺陷,任何多余的空间从何而来?

更新: 错误是在var tmp = Encoding.Unicode.GetBytes(text); 行,将Unicode更改为ASCII。


阅读 168

收藏
2021-07-01

共1个答案

admin

如果您使用的是SQL Anywhere
16.0或更高版本,则可以使用解密函数的’format = raw’选项进行此操作。如果使用的版本早于该版本,则解密功能将无法解密在数据库服务器外部加密的数据。

更新: 由于您更新了问题,因此我也将予以解决。我在SQL
Anywhere服务器中进行了解密,结果出来的数据中包含嵌入的NULL,这意味着加密的数据已经包含嵌入的NULL。我不是C#专家,所以我不能肯定地告诉您,但是我怀疑var text = "stuff";会将数据存储在UTF-16中。

全面披露:我在SQL Anywhere工程领域的SAP工作。

2021-07-01