3

我正在尝试将 WP8 应用程序移植到 Win 8.1 商店应用程序。该应用程序使用基于密码的 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 代码。

4

0 回答 0