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);
}
Расшифровка с использованием 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 байта.
Помогите!
1 ответ
Это звучит как проблема заполнения.
Если посмотреть на исходный код базового класса SymmetricAlgorithm в.NET, который является основой AesCryptoServiceProvider, для заполнения по умолчанию используется PaddingMode.PKCS7. Похоже, вы не определили режим заполнения, поэтому я бы предположил, что по умолчанию все еще применяется.
Хотя я раньше не использовал библиотеку PCLCrypto, для быстрого ознакомления с github есть пара алгоритмов AesEcb: AesEcb и AesEcbPkcs7. Отсутствие режима заполнения в имени AesEcb означало бы для меня, что он не имеет заполнения (и, следовательно, не удалил никакого заполнения), что будет эквивалентно PaddingMode.None в библиотеках.NET.
Попробуйте использовать алгоритм PCLCrypto.SymmetricAlgorithm.AesEcbPkcs7 в 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.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.