System.Security.Cryptography 与 PCLCrypto
System.Security.Cryptography vs PCLCrypto
我们正在删除系统中的许多共享功能并将其移植到 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);
}
使用PCL加密
解密
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 中基础 class 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
我们正在删除系统中的许多共享功能并将其移植到 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);
}
使用PCL加密
解密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 中基础 class 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