在Win RT和WP8中使用PBKDF2进行AES 256位密钥加密

时间:2013-10-29 16:00:29

标签: windows-phone-8

我正在尝试将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代码。

0 个答案:

没有答案