Metro WinRT应用程序中的AesManaged解密
本文关键字:AesManaged 解密 WinRT 应用程序 Metro | 更新日期: 2024-09-20 16:40:53
我有一些文本,由C#的AesManaged加密,必须在WinRT Metro应用程序中解密。我无法更改加密代码,因为该代码有其他无法更改的依赖项。
加密功能如下:
// Note: Edited out possibly real password and salt:
Guid password = Guid.Parse("AAAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA");
Guid salt = Guid.Parse("AAAAAAAAA-BBBB-BBBB-BBBB-AAAAAAAAAAAA");
string EncryptedValue(string data)
{
byte[] passwordBytes = password.ToByteArray();
byte[] saltBytes = salt.ToByteArray();
byte[] bKey = new byte[16];
for(int i = 0; i < 16; i++)
{
bKey[i] = passwordBytes[i];
}
string encryptedData = String.Empty;
using (System.Security.Cryptography.AesManaged aesAlg = new System.Security.Cryptography.AesManaged())
{
aesAlg.Key = bKey;
aesAlg.IV = saltBytes;
// Create a decrytor to perform the stream transform.
System.Security.Cryptography.ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (System.Security.Cryptography.CryptoStream csEncrypt = new System.Security.Cryptography.CryptoStream(msEncrypt, encryptor, System.Security.Cryptography.CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(data);
}
encryptedData = Convert.ToBase64String(msEncrypt.ToArray());
}
}
}
return encryptedData;
}
示例数据:
// Decrypted value is: 2029
var _id = EncryptedSettingsBase.Decrypt("ROSNJ1XnAozF7LC0wW8AOg==");
我阅读了以下帖子:http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/7cfcc576-1c2c-4a50-a546-09a45d3ff41f这看起来是同样的问题,但我还没能得到他们的建议,因为我得到了异常:"数据错误(循环冗余检查)"。(HRESULT:0x80070017中出现异常)'。
internal class EncryptedSettingsBase
{
public static string Decrypt(string cipherText)
{
var passwordBytes = (new Guid("AAAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")).ToByteArray();
var salt = (new Guid("AAAAAAAAA-BBBB-AAAA-AAAA-AAAAAAAAAAAA")).ToString();
byte[] bKey = new byte[16];
for (int i = 0; i < 16; i++)
{
bKey[i] = passwordBytes[i];
}
IBuffer pwBuffer = CryptographicBuffer.CreateFromByteArray(bKey);
IBuffer saltBuffer = CryptographicBuffer.ConvertStringToBinary(salt, BinaryStringEncoding.Utf16LE);
IBuffer cipherBuffer = CryptographicBuffer.DecodeFromBase64String(cipherText);
// Derive key material for password size 32 bytes for AES256 algorithm
KeyDerivationAlgorithmProvider keyDerivationProvider = KeyDerivationAlgorithmProvider.OpenAlgorithm("PBKDF2_SHA1");
// using salt and 1000 iterations
KeyDerivationParameters pbkdf2Parms = KeyDerivationParameters.BuildForPbkdf2(saltBuffer, 1000);
// create a key based on original key and derivation parmaters
CryptographicKey keyOriginal = keyDerivationProvider.CreateKey(pwBuffer);
IBuffer keyMaterial = CryptographicEngine.DeriveKeyMaterial(keyOriginal, pbkdf2Parms, 32);
CryptographicKey derivedPwKey = keyDerivationProvider.CreateKey(pwBuffer);
// derive buffer to be used for encryption salt from derived password key
IBuffer saltMaterial = CryptographicEngine.DeriveKeyMaterial(derivedPwKey, pbkdf2Parms, 16);
// display the keys - because KeyDerivationProvider always gets cleared after each use, they are very similar unforunately
string keyMaterialString = CryptographicBuffer.EncodeToBase64String(keyMaterial);
string saltMaterialString = CryptographicBuffer.EncodeToBase64String(saltMaterial);
SymmetricKeyAlgorithmProvider symProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm("AES_CBC_PKCS7");
// create symmetric key from derived password material
CryptographicKey symmKey = symProvider.CreateSymmetricKey(keyMaterial);
// encrypt data buffer using symmetric key and derived salt material
IBuffer resultBuffer = CryptographicEngine.Decrypt(symmKey, cipherBuffer, saltMaterial);
string result = CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf16LE, resultBuffer);
return result;
}
}
我可能在做一些愚蠢的事情,但我并不完全理解这些东西。有人知道我哪里错了吗?
非常感谢您的帮助。
干杯,Jon
您在一侧使用PBKDF2,而在.net部分没有PBKDF2。不幸的是,您无法更改的部分没有正确使用密钥;它只是直接使用UID。
如果我可以更改所有依赖项以正确加密,那么下面的代码就成功了:
此处的代码有助于:http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2966549-make-equal-aesmanaged-snippet-as-in-silverlight-an
加密代码,C#4.0侧:
string salt = "AAAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA";
string password = "AAAAAAAAA-BBBB-AAAA-AAAA-AAAAAAAAAAAA";
string EncryptedValue(string data)
{
byte[] saltBytes = System.Text.Encoding.UTF8.GetBytes(salt);
string encryptedData = String.Empty;
using (System.Security.Cryptography.AesManaged aes = new System.Security.Cryptography.AesManaged())
{
var rfc = new System.Security.Cryptography.Rfc2898DeriveBytes(password, saltBytes);
aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
aes.KeySize = aes.LegalKeySizes[0].MaxSize;
aes.Key = rfc.GetBytes(32);
rfc.Reset();
aes.IV = rfc.GetBytes(16);
// Create a decrytor to perform the stream transform.
System.Security.Cryptography.ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (System.Security.Cryptography.CryptoStream csEncrypt = new System.Security.Cryptography.CryptoStream(msEncrypt, encryptor, System.Security.Cryptography.CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
// Write all data to the stream.
swEncrypt.Write(data);
}
encryptedData = Convert.ToBase64String(msEncrypt.ToArray());
}
}
}
return encryptedData;
}
解密代码WinRT侧:
protected string Decrypt(string encryptedData)
{
const string password = "AAAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA";
const string salt = "AAAAAAAAA-BBBB-AAAA-AAAA-AAAAAAAAAAAA";
IBuffer pwBuffer = CryptographicBuffer.ConvertStringToBinary(password, BinaryStringEncoding.Utf8);
IBuffer saltBuffer = CryptographicBuffer.ConvertStringToBinary(salt, BinaryStringEncoding.Utf8);
IBuffer cipherBuffer = CryptographicBuffer.DecodeFromBase64String(encryptedData);
KeyDerivationAlgorithmProvider keyDerivationProvider = KeyDerivationAlgorithmProvider.OpenAlgorithm("PBKDF2_SHA1");
KeyDerivationParameters pbkdf2Parms = KeyDerivationParameters.BuildForPbkdf2(saltBuffer, 1000);
CryptographicKey keyOriginal = keyDerivationProvider.CreateKey(pwBuffer);
IBuffer keyMaterial = CryptographicEngine.DeriveKeyMaterial(keyOriginal, pbkdf2Parms, 32);
CryptographicKey derivedPwKey = keyDerivationProvider.CreateKey(pwBuffer);
IBuffer saltMaterial = CryptographicEngine.DeriveKeyMaterial(derivedPwKey, pbkdf2Parms, 16);
SymmetricKeyAlgorithmProvider symProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm("AES_CBC_PKCS7");
CryptographicKey symmKey = symProvider.CreateSymmetricKey(keyMaterial);
IBuffer resultBuffer = CryptographicEngine.Decrypt(symmKey, cipherBuffer, saltMaterial);
byte[] asd;
CryptographicBuffer.CopyToByteArray(resultBuffer, out asd);
string result = CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, resultBuffer);
return result;
}