如何在Windows运行时实现AES加密(AesManaged Rfc2898DeriveBytes) [英] How to implement AES Encrypt (AesManaged Rfc2898DeriveBytes) in Windows Runtime

查看:1211
本文介绍了如何在Windows运行时实现AES加密(AesManaged Rfc2898DeriveBytes)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试将我的项目从Windows Phone Silverlight 8.1移植到Windows Runtime时遇到阻止问题。
在Windows Runtime中,AES加密的字符串与Silverlight之前的字符串不同。

I met a blocking issue when I tried to immigrate my project from Windows Phone Silverlight 8.1 to Windows Runtime. In Windows Runtime the AES-encrypted string is not the same as the one on Silverlight before.

在Silverlight中: / p>

In Silverlight:

    public static string EncryptAES(string encryptString)
    {
        AesManaged aes = null;
        MemoryStream ms = null;
        CryptoStream cs = null;

        string encryptKey = "testtest123";
        string salt = "abcabcabcd";
        try
        {
            Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(encryptKey, Encoding.UTF8.GetBytes(salt));

            aes = new AesManaged();
            aes.Key = rfc2898.GetBytes(aes.KeySize / 8);
            aes.IV = rfc2898.GetBytes(aes.BlockSize / 8);

            ms = new MemoryStream();
            cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write);

            byte[] data = Encoding.UTF8.GetBytes(encryptString);
            cs.Write(data, 0, data.Length);
            cs.FlushFinalBlock();

            return Convert.ToBase64String(ms.ToArray());
        }
        catch
        {
            return encryptString;
        }
        finally
        {
            if (cs != null)
                cs.Close();

            if (ms != null)
                ms.Close();

            if (aes != null)
                aes.Clear();
        }
    }

在Windows Runtime中:

In Windows Runtime:

    public static string EncryptAES(string plainText)
    {
        string pw = "testtest123";
        string salt = "abcabcabcd";
        IBuffer plainBuffer = CryptographicBuffer.ConvertStringToBinary(plainText, BinaryStringEncoding.Utf8);

        IBuffer saltBuffer = CryptographicBuffer.ConvertStringToBinary(salt, BinaryStringEncoding.Utf8);
        IBuffer pwBuffer = CryptographicBuffer.ConvertStringToBinary(pw, BinaryStringEncoding.Utf8);

        KeyDerivationAlgorithmProvider keyDerivationProvider = Windows.Security.Cryptography.Core.KeyDerivationAlgorithmProvider.OpenAlgorithm(KeyDerivationAlgorithmNames.Pbkdf2Sha256);
        // 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 buffers - because KeyDerivationProvider always gets cleared after each use, they are very similar unforunately
        string keyMaterialString = CryptographicBuffer.EncodeToBase64String(keyMaterial);
        string saltMaterialString = CryptographicBuffer.EncodeToBase64String(saltMaterial);
        //AES_CBC_PKCS7
        SymmetricKeyAlgorithmProvider symProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm("AES_CBC_PKCS7");
        // create symmetric key from derived password key
        CryptographicKey symmKey = symProvider.CreateSymmetricKey(keyMaterial);

        // encrypt data buffer using symmetric key and derived salt material
        IBuffer resultBuffer = CryptographicEngine.Encrypt(symmKey, plainBuffer, saltMaterial);
        string result = CryptographicBuffer.EncodeToBase64String(resultBuffer);
        return result;
    }

在Silverlight项目中,AES加密的字符串123456是4UfdhC / 0MFQlMhl7N7gqLg ==;
在Windows Runtime Project中,AES加密的字符串是jxsR5EuhPXgRsHLs4N3EGQ ==

In Silverlight Project, string "123456" encrypted by AES is "4UfdhC/0MFQlMhl7N7gqLg=="; While in Windows Runtime Project, the AES-encrypted string is "jxsR5EuhPXgRsHLs4N3EGQ=="

那么如何在WinRT上获取相同的字符串在Silverlight上的一个?

推荐答案

AES类默认为Microsoft运行时的随机IV。要获得相同的密文,你需要使用静态IV。然而这不安全。相反,你应该检查你是否获得相同的密钥字节,并让密文每次运行不同。

The AES classes default to a random IV on the Microsoft runtimes. To get the same ciphertext you'll need to use a static IV. That's however not secure. Instead you should just check if you get the same key bytes and let the ciphertext differ for each run. Otherwise you can clearly distinguish identical plaintext.

您似乎也使用了错误的哈希算法, Rfc2898DeriveBytes 使用SHA -1而不是SHA-256作为底层哈希函数。

You also seem to be using the wrong hash algorithm, Rfc2898DeriveBytes uses SHA-1 instead of SHA-256 as underlying hash function.

这篇关于如何在Windows运行时实现AES加密(AesManaged Rfc2898DeriveBytes)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆