c# - Metro WinRT 应用程序中的 AesManaged 解密

标签 c# cryptography aes windows-runtime

我有一些文本,由 C# 的 AesManaged 加密,必须在 WinRT Metro 应用程序中解密。我无法更改加密代码,因为该代码具有其他无法更改的依赖项。

加密函数如下所示:

// Note: Edited out possibly real password and salt:
Guid password = Guid.Parse("AAAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA");
Guid salt = Guid.Parse("AAAAAAAAA-BBBB-BBBB-BBBB-AAAAAAAAAAAA");

string EncryptedValue(string data)
{   
byte[] passwordBytes = password.ToByteArray();
byte[] saltBytes = salt.ToByteArray();

byte[] bKey = new byte[16];
for(int i = 0; i < 16; i++)
{
    bKey[i] = passwordBytes[i];
}

string encryptedData = String.Empty;
using (System.Security.Cryptography.AesManaged aesAlg = new System.Security.Cryptography.AesManaged())
{
    aesAlg.Key = bKey;
    aesAlg.IV = saltBytes;

    // Create a decrytor to perform the stream transform.
    System.Security.Cryptography.ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.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;
}

示例数据:

   // Decrypted value is: 2029
   var _id = EncryptedSettingsBase.Decrypt("ROSNJ1XnAozF7LC0wW8AOg==");

我阅读了以下帖子: http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/7cfcc576-1c2c-4a50-a546-09a45d3ff41f 这看起来像是同一个问题,但是我无法让他们的建议起作用,因为我得到了异常:“数据错误(循环冗余检查)”。 (HRESULT 的异常:0x80070017)'。

internal class EncryptedSettingsBase
{
    public static string Decrypt(string cipherText)
    {
        var passwordBytes = (new Guid("AAAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")).ToByteArray();
        var salt = (new Guid("AAAAAAAAA-BBBB-AAAA-AAAA-AAAAAAAAAAAA")).ToString();

        byte[] bKey = new byte[16];
        for (int i = 0; i < 16; i++)
        {
            bKey[i] = passwordBytes[i];
        }

        IBuffer pwBuffer = CryptographicBuffer.CreateFromByteArray(bKey);
        IBuffer saltBuffer = CryptographicBuffer.ConvertStringToBinary(salt, BinaryStringEncoding.Utf16LE);
        IBuffer cipherBuffer = CryptographicBuffer.DecodeFromBase64String(cipherText);

        // Derive key material for password size 32 bytes for AES256 algorithm
        KeyDerivationAlgorithmProvider keyDerivationProvider = KeyDerivationAlgorithmProvider.OpenAlgorithm("PBKDF2_SHA1");
        // 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 keys - because KeyDerivationProvider always gets cleared after each use, they are very similar unforunately
        string keyMaterialString = CryptographicBuffer.EncodeToBase64String(keyMaterial);
        string saltMaterialString = CryptographicBuffer.EncodeToBase64String(saltMaterial);

        SymmetricKeyAlgorithmProvider symProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm("AES_CBC_PKCS7");
        // create symmetric key from derived password material
        CryptographicKey symmKey = symProvider.CreateSymmetricKey(keyMaterial);

        // encrypt data buffer using symmetric key and derived salt material
        IBuffer resultBuffer = CryptographicEngine.Decrypt(symmKey, cipherBuffer, saltMaterial);
        string result = CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf16LE, resultBuffer);
        return result;
    }
}

我可能在做一些愚蠢的事情,但我并不完全理解这些东西。有人知道我哪里出错了吗?

非常感谢任何帮助。

干杯, 乔恩

最佳答案

您在一侧使用 PBKDF2 而在 .net 部分没有使用 PBKDF2。不幸的是,您无法更改的部分没有正确使用 key ;它只是直接使用 UID。

关于c# - Metro WinRT 应用程序中的 AesManaged 解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11764891/

相关文章:

c# - 如何将一个 razor 页面包含到另一个 razor 页面?

c# - Code First 类型 '' 上的属性 '' 上的ForeignKeyAttribute 无效。 Entity Framework

python - Python 中的 XTEA 测试向量

security - 隐藏 key 的最佳位置?

Java加密与解密

Java cipher.doFinal() 写入额外的字节

c# - "Database is locked"SQLite 和 C#

c# - Entity Framework 使用扩展方法抛出异常

java - 从文件实例化 JavaKeyStore 时遇到问题

java - 使用 AES 缓存用户密码 -- BadPaddingException