我们正在努力在我们的系统中挖掘大量共享功能并将其移植到PCL库中.我在使用PCLCrypto时遇到了问题.我正在我们的数据库中获取一些现有数据,并尝试使用相同的算法对其进行解密.我得到了值,但最后有16个额外的字节只是垃圾.
见下面的代码:
使用System.Security.Cryptography的旧算法
public static string SymmetricEncrypt(this string plaintext,string key,SymmetricAlgorithm algorithm) { byte[] keyBuffer = Convert.FromBase64String(key.Hash(HashAlgorithm.MD5)); byte[] plainTextBuffer = Encoding.UTF8.GetBytes(plaintext); var symmetricAlgorithm = new AesCryptoServiceProvider(); symmetricAlgorithm.Key = keyBuffer; symmetricAlgorithm.Mode = CipherMode.ECB; var encryptor = symmetricAlgorithm.CreateEncryptor(); byte[] cipherBuffer = encryptor.TransformFinalBlock(plainTextBuffer,plainTextBuffer.Length); symmetricAlgorithm.Clear(); return Convert.ToBase64String(cipherBuffer); } public static string SymmetricDecrypt(this string cipherText,SymmetricAlgorithm algorithm) { byte[] keyBuffer = Convert.FromBase64String(key.Hash(HashAlgorithm.MD5)); byte[] cipherTextBuffer = Convert.FromBase64String(cipherText); var symmetricAlgorithm = new AesCryptoServiceProvider(); symmetricAlgorithm.Key = keyBuffer; symmetricAlgorithm.Mode = CipherMode.ECB; var decryptor = symmetricAlgorithm.CreateDecryptor(); byte[] plainTextBuffer = decryptor.TransformFinalBlock(cipherTextBuffer,cipherTextBuffer.Length); symmetricAlgorithm.Clear(); return Encoding.Default.GetString(plainTextBuffer); }
使用PCLCrypto解密
public static string SymmetricDecrypt(this string cipherText,SymmetricAlgorithm algorithm) { byte[] keyBuffer = Convert.FromBase64String(key.Hash(HashAlgorithm.MD5)); byte[] cipherTextBuffer = Convert.FromBase64String(cipherText); ISymmetricKeyAlgorithmProvider symmetricAlgorithm = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(PCLCrypto.SymmetricAlgorithm.AesEcb); var symmetricKey = symmetricAlgorithm.CreateSymmetricKey(keyBuffer); var decryptor = WinRTCrypto.CryptographicEngine.CreateDecryptor(symmetricKey); byte[] plainTextBuffer = decryptor.TransformFinalBlock(cipherTextBuffer,cipherTextBuffer.Length); return UTF8Encoding.UTF8.GetString(plainTextBuffer,plainTextBuffer.Length); }
使用旧版本:plainTextBuffer是16个字节,新版本是32个字节.
救命!
解决方法
这听起来像填充问题.
查看.NET中基类SymmetricAlgorithm的源代码,它是AesCryptoServiceProvider的基础,默认填充是PaddingMode.PKCS7.您似乎没有定义填充模式,因此我认为默认仍然适用.
虽然我以前没有使用过PCLCrypto库,但是快速浏览一下github有几种AesEcb算法:AesEcb和AesEcbPkcs7.从AesEcb的名称缺少填充模式将意味着它没有填充(因此没有删除任何填充),这将相当于.NET库中的PaddingMode.None.
尝试在PCLCrypto中使用PCLCrypto.SymmetricAlgorithm.AesEcbPkcs7算法,看看是否删除了在输出结尾处看到的填充.
更新
我刚刚对此进行了测试,它似乎正常工作并删除了您将看到的填充:
public static string SymmetricDecrypt(this string cipherText,SymmetricAlgorithm algorithm) { byte[] keyBuffer = Convert.FromBase64String(key.Hash(HashAlgorithm.MD5)); byte[] cipherTextBuffer = Convert.FromBase64String(cipherText); ISymmetricKeyAlgorithmProvider symmetricAlgorithm = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(PCLCrypto.SymmetricAlgorithm.AesEcbPkcs7); var symmetricKey = symmetricAlgorithm.CreateSymmetricKey(keyBuffer); var decryptor = WinRTCrypto.CryptographicEngine.CreateDecryptor(symmetricKey); byte[] plainTextBuffer = decryptor.TransformFinalBlock(cipherTextBuffer,plainTextBuffer.Length); }
唯一的变化是将算法从PCLCrypto.SymmetricAlgorithm.AesEcb更改为PCLCrypto.SymmetricAlgorithm.AesEcbPkcs7