3

有人问我,如果我知道密钥,我将如何解密给定的 AES 256 位加密字符串。我对加密不是很熟悉,所以我坐下来研究这个问题。

在 MSDN 上找到了这个示例,并尝试将其修改为仅进行解密:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

internal class AesExample
{
    public static void Main()
    {
        var encryptedString = "U2FsdGVkX1/cHT8XuHCfpw0AV4jpaO8JfLqUeCRJqjY=";
        var secret = "SPARKY";

        // I know this is not the correct way to get my input byte arrays...
        // Just illustrating that I DO need byte arrays.
        var encryptedBytes = Encoding.UTF8.GetBytes(encryptedString);
        var secretBytes = Encoding.UTF8.GetBytes(secret);

        try
        {
            using (var aes = new AesManaged())
            {
                aes.Key = secretBytes;

                // Decrypt the bytes to a string. 
                var decryptedString = Decrypt(encryptedBytes, aes.Key, aes.IV);

                //Display the original data and the decrypted data.
                Console.WriteLine("Encrypted: {0}", encryptedString);
                Console.WriteLine("Decrypted: {0}", decryptedString);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("Error: {0}", e.Message);
        }
    }

    private static string Decrypt(byte[] cipherText, byte[] key, byte[] iv)
    {
        // Declare the string used to hold 
        // the decrypted text. 
        string plaintext;

        // Create an AesManaged object 
        // with the specified key and IV. 
        using (var aes = new AesManaged())
        {
            aes.Key = key;
            aes.IV = iv;

            // Create a decrytor to perform the stream transform.
            var decryptor = aes.CreateDecryptor(aes.Key, aes.IV);

            // Create the streams used for decryption. 
            using (var msDecrypt = new MemoryStream(cipherText))
            {
                using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (var srDecrypt = new StreamReader(csDecrypt))
                    {
                        // Read the decrypted bytes from the decrypting stream 
                        // and place them in a string.
                        plaintext = srDecrypt.ReadToEnd();
                    }
                }
            }
        }

        return plaintext;
    }
}

当然,只要我点击以下行,就会引发 CryptographicExcetion,并显示消息“指定的密钥不是该算法的有效大小”。==> aes.Key = secretBytes

有人建议对秘密进行 SHA1 哈希并将其修剪为 20 个字节。我试过了,然后我开始收到一个新的 CryptographicException 消息“要解密的数据长度无效”。

所以,我有几个问题:

1)仅给定加密文本和密钥,这是否可能?

2)如果是这样,它们是否需要做出一些基本假设,例如 CipherMode?我在读到 ECB 模式没有初始化向量。这就是我问的原因。

3)我需要做什么才能将输入(加密文本和密钥)放入正确的 Byte[] 格式以便解密工作?

谢谢!

4

2 回答 2

10

您可能需要更多信息才能完成这项工作。要回答您的具体问题:

  1. 是的,除了你没有密钥。正如 DavidH 所提到的,“SPARKY”不是有效的 AES 密钥,尽管密码通常用于通过所谓的密钥派生函数来派生密钥。您可以尝试通过(.NET 中流行的 KDF)运行您的密码以派生可能有效的不同 AES 密钥,但它也需要您显然没有的参数。您还可以尝试密码的各种 SHA 哈希摘要,但 20 字节再次不是有效的 AES 密钥 - 您需要 16、24 或 32 字节的密钥。Rfc2898DeriveBytes
  2. 如果您没有 IV,那么是的,您必须假设加密使用 ECB。(但请注意,一般情况下您不应该使用 ECB 模式。)
  3. 您的加密字符串似乎是使用 base64 编码的。在 .NET 中使用 .NET 将其转换为字节数组非常简单Convert.FromBase64String(encryptedString);

这听起来像是一个有趣的练习,但如果没有更多信息,你可能最终会感到沮丧。

于 2013-08-14T20:45:13.363 回答
2

AES 密钥长度为 128、192 和 256 位,具体取决于您要使用的密码。您必须确保您的字符串是适当的字节长度。

于 2013-08-14T20:25:39.957 回答