我有这种使用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)
我得到了这样的结果: s t u f f 东西
所以它几乎工作,以十六进制比较它是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); line,将Unicode更改为ASCII。
答案 0 :(得分:1)
如果您使用的是SQL Anywhere 16.0或更高版本,则可以使用decrypt function的'format = raw'选项执行此操作。如果您使用的是早于此版本的版本,则decrypt函数将无法解密在数据库服务器外部加密的数据。
更新:由于您更新了问题,我也会解决这个问题。我在SQL Anywhere服务器中运行了解密,并且出来的数据中包含嵌入的NULL,这意味着加密的数据已经包含嵌入的NULL。我不是C#家伙,所以我无法确切地告诉你,但我怀疑var text = "stuff";
将数据存储在UTF-16中。
完全披露:我在SQL Anywhere工程中为SAP工作。