我正在尝试将WP8应用程序移植到Win 8.1商店App。该应用程序使用基于密码的AES 256进行加密。我遇到的困惑是,我能够解密来自WP8的文本,使用256位密钥加密,但只使用Win RT中的32位密钥。
以下是Window Phone 8代码。请注意,Rfc2898DeriveBytes需要以字节为单位,因此使用的密钥是256位。
private static string Decrypt(string dataToDecrypt, string password, string salt)
{
AesManaged aes = null;
MemoryStream memoryStream = null;
try
{
//Generate a Key based on a Password and HMACSHA1 pseudo-random number generator
Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(salt), 10000);
//Create AES algorithm
aes = new AesManaged();
aes.KeySize = aes.LegalKeySizes[0].MaxSize; // returns 256
aes.BlockSize = aes.LegalBlockSizes[0].MaxSize; // return 128
aes.Key = rfc2898.GetBytes(aes.KeySize);
aes.IV = rfc2898.GetBytes(aes.BlockSize);
//Create Memory and Crypto Streams
memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream, aes.CreateDecryptor(), CryptoStreamMode.Write);
//Decrypt Data
byte[] data = Convert.FromBase64String(dataToDecrypt);
cryptoStream.Write(data, 0, data.Length);
cryptoStream.FlushFinalBlock();
//Return Decrypted String
byte[] decryptBytes = memoryStream.ToArray();
//Dispose
if (cryptoStream != null)
cryptoStream.Dispose();
//Retval
return Encoding.UTF8.GetString(decryptBytes, 0, decryptBytes.Length);
}
catch (Exception ex)
{
MasterData.CryptographyExceptionOccured = true;
Debug.WriteLine(ex.Message);
Debug.WriteLine(ex.StackTrace);
return "";
}
finally
{
if (memoryStream != null)
memoryStream.Dispose();
if (aes != null)
aes.Clear();
}
}
下面是Win RT代码(Win 8.1)请注意,CryptographicEngine.DeriveKeyMaterial方法需要以位为单位的密钥大小。但我能够使用下面的Win RT代码解密WP8中的256位加密,这似乎只使用了32位。 (WP8 / Win RT中使用的密码和盐相同)
private static void GenerateKeyMaterial(string password, string salt, uint iterationCount, out IBuffer keyMaterial, out IBuffer iv)
{
// Setup KDF parameters for the desired salt and iteration count
IBuffer saltBuffer = CryptographicBuffer.ConvertStringToBinary(salt, BinaryStringEncoding.Utf8);
KeyDerivationParameters kdfParameters = KeyDerivationParameters.BuildForPbkdf2(saltBuffer, iterationCount);
// Get a KDF provider for PBKDF2, and store the source password in a Cryptographic Key
KeyDerivationAlgorithmProvider kdf = KeyDerivationAlgorithmProvider.OpenAlgorithm(KeyDerivationAlgorithmNames.Pbkdf2Sha256);
// KeyDerivationAlgorithmProvider kdf = KeyDerivationAlgorithmProvider.OpenAlgorithm(KeyDerivationAlgorithmNames.Pbkdf2Sha1); IBuffer passwordBuffer = CryptographicBuffer.ConvertStringToBinary(password, BinaryStringEncoding.Utf8);
CryptographicKey passwordSourceKey = kdf.CreateKey(passwordBuffer);
// Generate key material from the source password, salt, and iteration count. Only call DeriveKeyMaterial once,
// since calling it twice will generate the same data for the key and IV.
int keySize = 256 / 8;
int ivSize = 128 / 8;
uint totalDataNeeded = (uint)(keySize + ivSize);
IBuffer keyAndIv = CryptographicEngine.DeriveKeyMaterial(passwordSourceKey, kdfParameters, totalDataNeeded);
// Split the derived bytes into a seperate key and IV
byte[] keyMaterialBytes = keyAndIv.ToArray();
keyMaterial = WindowsRuntimeBuffer.Create(keyMaterialBytes, 0, keySize, keySize);
iv = WindowsRuntimeBuffer.Create(keyMaterialBytes, keySize, ivSize, ivSize);
}
所以要在Win RT中使用256位加密,上面代码中的密钥大小应该是多少?如何使用32位密钥解密256位加密字符串。请参阅上面的WP8和Win RT代码。