none
在WinRT中怎么实现AesManaged Rfc2898DeriveBytes RRS feed

  • 问题

  • 最近做SL程序迁移到RT上,遇到一个AES加密问题,在Windows Phone8.1加密出来字符串跟原先SL不一样

    SL:

    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();
                }
            }

    WinRT:

     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.Pbkdf2Sha1);
                // 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;
            }

    在SL打印123456加密后字符串是:4UfdhC/0MFQlMhl7N7gqLg==

    在WinRT打印123456加密后字符串是:+0+aBgWnpnoh23rv8s+/0Q==

    折腾好久都看不出RT版本代码哪里不对。。。。


    609722679@qq.com



    • 已编辑 kanghhee 2015年4月8日 2:53
    2015年4月7日 16:14

全部回复

  • 你好,

    我也不确定问题出在哪里,不过你可以试试下面的silverlight版本,我测试了一下可以得到runtime一样的加密文本。

      string salt = "abcabcabcd";
            string password = "testtest123";
    
            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;
            }
    出处请看这里, http://stackoverflow.com/questions/11764891/aesmanaged-decryption-in-metro-winrt-application


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    2015年4月8日 6:47
  • 如果用SL版本 我上面贴出来SL版本可以用,现在迁移到RT不知道咋整

    609722679@qq.com

    2015年4月9日 12:26
  • 我这边测试的结果正好和你相反。你可以打包一个测试的可重现你问题的项目上来吗?我来看看在么回事。请使用任何的云空间保存你的项目,然后发一个链接上来。


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2015年4月10日 1:20
  • 代码在这里下载http://files.cnblogs.com/files/walleyekneel/AES.zip

    在app OnLaunched里面可以看到,主要winrt加密出来跟SL不一样。winrt aes算法改了? 


    609722679@qq.com

    2015年4月10日 14:58
  • 是的, 不同, 目前网上找不到完美的解决方法。

    它们的最大差异是RT需要rfc.Reset();

    2015年4月15日 9:57