给定加密文本和密码的C#AES 256位解密

时间:2013-08-14 19:31:55

标签: c# encryption aes

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

我找到了this example on MSDN,并试图修改它只做Decrypt:

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 []格式以使解密工作?

谢谢!

2 个答案:

答案 0 :(得分:10)

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

  1. 是的,但您没有密钥。正如DavidH所提到的,“SPARKY”不是有效的AES密钥,尽管密码通常用于通过所谓的key derivation functions派生密钥。您可以尝试通过Rfc2898DeriveBytes(.NET中一种流行的KDF)运行密码,以获得可能有效的不同AES密钥,但它也需要您显然没有的参数。您还可以尝试使用密码的各种SHA哈希摘要,但是再次20个字节不是有效的AES密钥 - 您需要16,24或32字节密钥。
  2. 如果您没有IV,那么是的,您必须假设加密使用ECB。 (但请注意,一般情况下你应该never use ECB mode。)
  3. 您的加密字符串似乎使用base64进行编码。使用Convert.FromBase64String(encryptedString);在.NET中将其转换为字节数组非常简单。
  4. 这听起来像一个有趣的练习,但你可能只是在没有更多信息的情况下最终会感到沮丧。

答案 1 :(得分:2)

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