System.Security.Cryptography与PCLCrypto

我们正在努力在我们的系统中挖掘大量共享function并将其移植到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, 0, plainTextBuffer.Length); symmetricAlgorithm.Clear(); return Convert.ToBase64String(cipherBuffer); } public static string SymmetricDecrypt(this string cipherText, string key, 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, 0, cipherTextBuffer.Length); symmetricAlgorithm.Clear(); return Encoding.Default.GetString(plainTextBuffer); } 

使用PCLCrypto解密

 public static string SymmetricDecrypt(this string cipherText, string key, 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, 0, cipherTextBuffer.Length); return UTF8Encoding.UTF8.GetString(plainTextBuffer, 0, 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, string key, 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, 0, cipherTextBuffer.Length); return UTF8Encoding.UTF8.GetString(plainTextBuffer, 0, plainTextBuffer.Length); } 

唯一的变化是将算法从PCLCrypto.SymmetricAlgorithm.AesEcb更改为PCLCrypto.SymmetricAlgorithm.AesEcbPkcs7