【问题标题】:How to decrypt with WinRT without changing existing encryption code in .NET Desktop App?如何在不更改 .NET 桌面应用程序中现有加密代码的情况下使用 WinRT 解密?
【发布时间】:2014-03-20 09:43:26
【问题描述】:

我对整个加密/解密 cr*p 有一点问题 ;-)

是否可以解密在 .NET 桌面应用程序中加密的 WinRt(Windows 应用商店应用程序)中的数据,反之亦然?我无法更改桌面应用程序的代码,因为它已在使用中。

我已经尝试了一些 WinRT 中 CryptographicEngine 的教程,但我从未得到与桌面应用程序中的结果相匹配的结果。

也许有人可以帮助我?我是 .NET 开发的新手,我从来没有真正对加密做过任何事情,所以我不知道我在做什么;-)

这是桌面应用程序中使用的一些代码 - 我无法更改该代码!

    private string pwd = "password";
    private string salt = "salt";

    public byte[] Encrypt(byte[] data)
    {
        PasswordDeriveBytes derivedPassword = new PasswordDeriveBytes(pwd, Encoding.ASCII.GetBytes(salt));
        byte[] key = derivedPassword.GetBytes(16);
        byte[] iv = Encoding.ASCII.GetBytes("1234567891234567");

        RijndaelManaged symmetricKey = new RijndaelManaged();
        symmetricKey.Mode = CipherMode.CBC;
        byte[] cipherBytes = null;

        using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor(key, iv))
        {
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                {
                    cryptoStream.Write(data, 0, data.Length);
                    cryptoStream.FlushFinalBlock();
                    cryptoStream.Close();
                    cipherBytes = ms.ToArray();
                    ms.Close();
                }
            }
        }

        symmetricKey.Clear();
        return cipherBytes;
    }

这是我在 WinRT 中尝试的示例方法 - 但结果与桌面应用程序的结果不同 (大部分代码来自http://blog.lordinaire.fr/2012/12/winrt-encryption-and-decryption-with-aes-algorithm/

已删除无效代码 - 请参阅编辑

我真的很感激一些帮助

来自奥地利的问候

编辑 我尝试了一些东西,但我仍然无法让它正常工作:( 我就是找不到正确的钥匙。尽管如此,为了测试加密,我对密钥进行了硬编码——然后它就可以工作了。

就像 Nate Diamond 建议的那样,我使用了 KeyDerivationAlogrithm 和一个空的盐和一个已经加盐的密码。一个问题是,我不知道如何“加盐”。我试着把盐放在前面、最后、中间并交替每个符号 - 仍然不是正确的键:( 这是我使用的代码:

    // password = 11112222333344445555  // salt = aaaabbbbccccddddeeee
    private string password = "11112222333344445555aaaabbbbccccddddeeee";
    private byte[] salt = new byte[20];
    private uint iterationCount = 100;

    private static byte[] keyBytes = null;
    public static byte[] KeyBytes
    {
        get
        {
            //for (int i = 0; i < salt.Length; i++)
            //{
            //    salt[i] = 0;
            //}

            // Setup KDF parameters for the desired salt and iteration count
            KeyDerivationParameters kdfParameters = KeyDerivationParameters.BuildForPbkdf2(CryptographicBuffer.CreateFromByteArray(salt), iterationCount);

            // Get a KDF provider for PBKDF2, and store the source password in a Cryptographic Key
            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.
            uint totalDataNeeded = 16;
            IBuffer keyAndIv = CryptographicEngine.DeriveKeyMaterial(passwordSourceKey, kdfParameters, totalDataNeeded);

            // Split the derived bytes into a seperate key and IV
            keyBytes = keyAndIv.ToArray();


            return keyBytes;
        }
    }

这里是我的加密方法的代码 - 它产生的结果与 .NET 桌面应用程序中的结果相同:)

private byte[] btVector = Encoding.UTF8.GetBytes("1234567891234567");
private byte[] keyBytes = Encoding.UTF8.GetBytes("123456789123456789123456");

public byte[] Encrypt(byte[] data)
    {
        // Get the key and iv and put all into IBuffers
        IBuffer keyBuffer = WindowsRuntimeBuffer.Create(KeyBytes, 0, 16, 16); ;
        IBuffer iv = WindowsRuntimeBuffer.Create(InitialVectorBytes, 0, 16, 16);
        IBuffer plainText = CryptographicBuffer.CreateFromByteArray(data);
        byte[] encryptedData;

        // Setup an AES key, using AES in CBC mode and applying PKCS#7 padding on the input
        SymmetricKeyAlgorithmProvider aesProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);
        CryptographicKey aesKeySymm = aesProvider.CreateSymmetricKey(keyBuffer);

        // Encrypt the data and convert it to byte array
        IBuffer encrypted = CryptographicEngine.Encrypt(aesKeySymm, plainText, iv);
        CryptographicBuffer.CopyToByteArray(encrypted, out encryptedData);
        return encryptedData;
    }

【问题讨论】:

  • 你的 WinRt 代码在哪里?你能补充一下吗?
  • 我尝试了几种不同的方法,但都没有真正奏效,其中大部分来自一些教程。但我可以添加它,当然:)
  • 虽然函数名和类名不完全一致,但大多数功能都在那里。通常只需遍历代码并找到相应的等价物。
  • 我认为主要问题是,桌面应用程序已经有几年历史了,例如使用 PasswordDeriveBytes 方法,我发现该方法使用 PBKDF1 而在 WinRT 中只有 PBKDF2 但正如我说,我从来没有对密码学做过任何事情,所以我不知道这是否相关

标签: c# .net encryption windows-8 windows-runtime


【解决方案1】:

PBKDF[1/2] 基本上是这样的:

1. Take a password.  
2. Add a salt.  
3. Hash the combined password and salt.  Store in `result`
4. For (number of iterations)
    1. Hash `result`, store in `result`.

PBKDF1 和 PBKDF2 的最大区别在于步骤 4 的第一部分。在 PBKDF1 中,它与打印的一样。在 PBKDF2 中,它变为:

4. For (number of iterations)
    1. Combine `result` and `salt`. Store in `result`
    2. Hash `result`, store in `result`.

所以,你有几个选择。

选项 1:

创建 PBKDF1 的自定义实现。 HashAlgorithmProvider 使得重复哈希结果变得非常容易。

选项 2:

使用 PBKDF2 和一个空的 salt byte 数组并将盐和密码组合为您的 secret。这应该与 PBKDF1 具有相同的效果。

应该注意的是,如果可能的话,您应该改用 PBKDF2。

希望这对编码有所帮助!

【讨论】:

  • 感谢您的回复,我想我会选择第二个选项 - 我希望它会起作用!只有一个问题,我究竟该如何将盐与密码结合起来?只是把盐放在最后?是的,我知道 PBKDF1 并不安全,但不幸的是我无法更改 .NET 应用程序...
猜你喜欢
  • 2019-03-01
  • 2020-05-22
  • 2018-01-25
  • 1970-01-01
  • 2012-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多