AES 加密 Windows Phone 8.1

AES Encryption Windows Phone 8.1

我需要对 Windows Phone 8.1 中的应用程序进行 128 位 AES 加密。我分别使用以下代码对数据进行加密和解密:

    private string GetEncryptedContent(string content)
    {
        byte[] keyMaterial = Encoding.UTF8.GetBytes(EncryptionKey);
        byte[] data = Encoding.UTF8.GetBytes(content);
        var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
        var key = provider.CreateSymmetricKey(keyMaterial);
        byte[] cipherText = WinRTCrypto.CryptographicEngine.Encrypt(key, data, null);
        return Encoding.UTF8.GetString(cipherText, 0, cipherText.Length);
    }

    private string GetDecryptedContent(string content)
    {
        byte[] keyMaterial = Encoding.UTF8.GetBytes(EncryptionKey);
        byte[] data = Encoding.UTF8.GetBytes(content);
        var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
        var key = provider.CreateSymmetricKey(keyMaterial);
        byte[] cipherText = WinRTCrypto.CryptographicEngine.Decrypt(key, data, null);
        return Encoding.UTF8.GetString(cipherText, 0, cipherText.Length);
    }

但是加密和解密似乎没有正常进行。它被加密为一些 unicode 字符并在解密时抛出崩溃:

Length is not a multiple of block size and no padding is selected.\r\nParameter name: ciphertext

我在这里做错了什么?有人可以帮忙吗?

编辑

用了很多时间Google后,我发现了以下加密和解密的方法,但它们似乎也不起作用。

    public string GetEncryptedContent(string input, string pass)
    {
        SymmetricKeyAlgorithmProvider SAP = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);
        CryptographicKey AES;
        HashAlgorithmProvider HAP = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);
        CryptographicHash Hash_AES = HAP.CreateHash();

        string encrypted = "";
        try
        {
            byte[] hash = new byte[32];
            Hash_AES.Append(CryptographicBuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(pass)));
            byte[] temp;
            CryptographicBuffer.CopyToByteArray(Hash_AES.GetValueAndReset(), out temp);

            Array.Copy(temp, 0, hash, 0, 16);
            Array.Copy(temp, 0, hash, 15, 16);

            AES = SAP.CreateSymmetricKey(CryptographicBuffer.CreateFromByteArray(hash));

            IBuffer Buffer = CryptographicBuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(input));
            encrypted = CryptographicBuffer.EncodeToBase64String(CryptographicEngine.Encrypt(AES, Buffer, null));

            return encrypted;
        }
        catch (Exception ex)
        {
            return null;
        }
    }


    public string GetDecryptedContent(string input, string pass)
    {
        SymmetricKeyAlgorithmProvider SAP = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);
        CryptographicKey AES;
        HashAlgorithmProvider HAP = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);
        CryptographicHash Hash_AES = HAP.CreateHash();

        string decrypted = "";
        try
        {
            byte[] hash = new byte[32];
            Hash_AES.Append(CryptographicBuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(pass)));
            byte[] temp;
            CryptographicBuffer.CopyToByteArray(Hash_AES.GetValueAndReset(), out temp);

            Array.Copy(temp, 0, hash, 0, 16);
            Array.Copy(temp, 0, hash, 15, 16);

            AES = SAP.CreateSymmetricKey(CryptographicBuffer.CreateFromByteArray(hash));

            IBuffer Buffer = CryptographicBuffer.DecodeFromBase64String(input);
            byte[] Decrypted;
            CryptographicBuffer.CopyToByteArray(CryptographicEngine.Decrypt(AES, Buffer, null), out Decrypted);
            decrypted = Encoding.UTF8.GetString(Decrypted, 0, Decrypted.Length);

            return decrypted;
        }
        catch (Exception ex)
        {
            return null;
        }
    }

编辑 2

终于设法让加密正常工作,但解密仍然无法正常工作,大概是因为我传递的编码不正确:

    private string GetEncryptedContent(string content)
    {
        byte[] keyMaterial = Encoding.UTF8.GetBytes(EncryptionKey);
        byte[] data = Encoding.UTF8.GetBytes(content);
        byte[] iv = new byte[128 / 8]; // Adding this solved the encryption issue.
        var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
        var key = provider.CreateSymmetricKey(keyMaterial);
        byte[] cipherText = WinRTCrypto.CryptographicEngine.Encrypt(key, data, iv);
        return Convert.ToBase64String(cipherText);
    }

    private string GetDecryptedContent(string content)
    {
        byte[] keyMaterial = Encoding.UTF8.GetBytes(EncryptionKey);
        byte[] data = Convert.FromBase64String(content); // Believe this is where the issue is, but not able to figure it out.
        byte[] iv = new byte[128 / 8]; // Added this to make the decryption work the same way.
        var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
        var key = provider.CreateSymmetricKey(keyMaterial);
        byte[] cipherText = WinRTCrypto.CryptographicEngine.Decrypt(key, data, iv);
        return Convert.ToBase64String(cipherText);
    }

我终于解决了这个问题。问题出在文本编码上。使用正确的编码解决了这个问题。下面的工作代码:

    public static string EncryptAES(string content, string password)
    {
        byte[] keyMaterial = Encoding.UTF8.GetBytes(password);
        byte[] data = Encoding.UTF8.GetBytes(content);
        byte[] iv = new byte[keyMaterial.Length];
        var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
        var key = provider.CreateSymmetricKey(keyMaterial);
        byte[] cipherText = WinRTCrypto.CryptographicEngine.Encrypt(key, data, iv);
        return Convert.ToBase64String(cipherText);
    }

    public static string DecryptAES(string content, string password)
    {
        byte[] keyMaterial = Encoding.UTF8.GetBytes(password);
        byte[] data = Convert.FromBase64String(content);
        byte[] iv = new byte[keyMaterial.Length];
        var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
        var key = provider.CreateSymmetricKey(keyMaterial);
        byte[] cipherText = WinRTCrypto.CryptographicEngine.Decrypt(key, data, iv);
        return Encoding.UTF8.GetString(cipherText, 0, cipherText.Length);
    }

WinRTCrypto 作为 PCLCrypto 的一部分可用。