【问题标题】:AES Encryption using RijndaelManged Class: Baes64 encoding and decoding aes encryption stringAES Encryption using RijndaelManged Class: Baes64编解码aes加密字符串
【发布时间】:2015-12-02 18:04:46
【问题描述】:

所以,我在解密解码的 base64 aes 字符串时遇到了问题。这可能吗?我写了一个小控制台程序来解决这个问题,但没有运气。这是我的例子:

如图所示,我已经成功地将 base64 转换回 aes 加密字符串,但是当我尝试解密它时,我得到了更多的垃圾。如果需要代码 sn-p,请告诉我。感谢大家的帮助 :) 更新:解密方法的代码sn-p

static void Main(string[] args)
    {
        string plainText;
        string decrypted;
        string decryptedFromB64EncodedDecoded;
        string fromBase64ToEncryptedText;
        string encryptedText;
        string encryptedTextBase64;
        byte[] encryptedBytes;

        byte[] encryptedBytes2;
        byte[] encryptedBytesBase64;

        RijndaelManaged crypto = new RijndaelManaged();

        UTF8Encoding UTF = new UTF8Encoding();

        Console.WriteLine("Please put in the text to be encrypted.");
        plainText = Console.ReadLine();

        try
        {
            encryptedBytes = encrypt(plainText, crypto.Key, crypto.IV);
            encryptedText = Encoding.ASCII.GetString(encryptedBytes);
            //encryptedBytes2 = Encoding.ASCII.GetBytes(encryptedText);

            encryptedTextBase64 = toBase64String(encryptedText);
            encryptedBytesBase64 = fromBase64String(encryptedTextBase64);

            fromBase64ToEncryptedText = Encoding.ASCII.GetString(encryptedBytesBase64);

            encryptedBytes2 = Encoding.ASCII.GetBytes(fromBase64ToEncryptedText);

            decrypted = decrypt(encryptedBytes, crypto.Key, crypto.IV);
            decryptedFromB64EncodedDecoded = decrypt(encryptedBytes2, crypto.Key, crypto.IV);

            Console.WriteLine("Start: {0}", plainText);
            Console.WriteLine("Encrypted: {0}", encryptedText);
            Console.WriteLine("Encrypted Base64: {0}", encryptedTextBase64);
            Console.WriteLine("From Base64 To AES Encypted Text: {0}", fromBase64ToEncryptedText);
            Console.WriteLine("Decrypted: {0}", decrypted);

            Console.WriteLine("Decrypted From Encode and then Decode Base64 Text: {0}", decryptedFromB64EncodedDecoded);

        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception: {0}", ex.Message);
        }

        Console.ReadLine();
    }

public static string decrypt (byte[] textToDecrypt, byte[] key, byte[] IV)
    {
        RijndaelManaged crypto = new RijndaelManaged();
        MemoryStream stream = new MemoryStream(textToDecrypt) ;
        ICryptoTransform decryptor = null;
        CryptoStream cryptoStream = null;
        StreamReader readStream = null;

        string text = string.Empty;

        try
        {
            crypto.Key = key;
            crypto.IV = IV;
            crypto.Padding = PaddingMode.None;

            decryptor = crypto.CreateDecryptor(crypto.Key, crypto.IV);
            cryptoStream = new CryptoStream(stream, decryptor, CryptoStreamMode.Read);
            //cryptoStream.Read(textToDecrypt, 0, textToDecrypt.Length);
            readStream = new StreamReader(cryptoStream);
            text = readStream.ReadToEnd();
            cryptoStream.Close();

            byte[] decodedValue = stream.ToArray();

            return text;
        }
        catch (Exception)
        {
            throw;
        }
        finally
        {
            if (crypto != null)
            {
                crypto.Clear();
            }
            stream.Flush();
            stream.Close();
        }
    }

public static byte[] encrypt(string text, byte[] key, byte[] IV)
    {
        RijndaelManaged crypto = null;
        MemoryStream stream = null;

        //ICryptoTransform is used to perform the actual decryption vs encryption, hash function are a version crypto transforms
        ICryptoTransform encryptor = null;
        //CryptoStream allows for encrption in memory
        CryptoStream cryptoStream = null;

        UTF8Encoding byteTransform = new UTF8Encoding();

        byte[] bytes = byteTransform.GetBytes(text);

        try
        {
            crypto = new RijndaelManaged();
            crypto.Key = key;
            crypto.IV = IV;

            stream = new MemoryStream();

            encryptor = crypto.CreateEncryptor(crypto.Key, crypto.IV);
            cryptoStream = new CryptoStream(stream, encryptor, CryptoStreamMode.Write);
            cryptoStream.Write(bytes, 0, bytes.Length);

        }
        catch (Exception)
        {

            throw;
        }
        finally
        {
            if (crypto != null)
            {
                crypto.Clear();
            }
            cryptoStream.Close();
        }

        return stream.ToArray();
    }

 public static string toBase64String(string value)
    {
        UTF8Encoding UTF = new UTF8Encoding();
        byte[] myarray =  UTF.GetBytes(value);
        return Convert.ToBase64String(myarray);
    }

    public static byte[] fromBase64String(string mystring)
    {
        //UTF8Encoding UTF = new UTF8Encoding();
        //byte[] myarray = UTF.GetBytes(value);
        return Convert.FromBase64String(mystring);
    }

【问题讨论】:

  • 我没有看到你的加密方法。我错过了什么吗?
  • 让我快速发布,不小心漏掉了,哈哈。
  • 很确定你的问题出在编码上。你能发布 toBase64String 和 fromBase64String 方法吗?
  • 是的,请稍等。

标签: c# aes rijndaelmanaged


【解决方案1】:

我不知道你是如何解密的,但在你解密之前,你应该将 base 64 字符串转换为字节数组,然后再将其发送到解密中。

byte[] encryptedStringAsBytes = Convert.FromBase64String(base64EncodedEncryptedValue);

然后使用字节数组,您可以通过 MemoryStream 传递给 CryptoStream。

更新

我认为问题在于您如何设置流

            using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
            {
                rijndaelManaged.Padding = paddingMode;
                rijndaelManaged.Key     = key;
                rijndaelManaged.IV      = initVector;

                MemoryStream memoryStream = null;
                try
                {
                    memoryStream = new MemoryStream(valueToDecrypt);
                    using (ICryptoTransform cryptoTransform = rijndaelManaged.CreateDecryptor())
                    {
                        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Read))
                        {
                            using (StreamReader streamReader = new StreamReader(cryptoStream))
                            {
                                return streamReader.ReadToEnd();                       
                            }
                        }
                    }
                }
                finally
                {
                    if (memoryStream != null)
                        memoryStream.Dispose();
                }
            }    

更新 2

这就是您基本上应该如何执行这些步骤的方式。

加密

  1. 使用 Encoding.GetBytes(stringToEncrypt) 对纯文本字符串进行编码
  2. 将 byte[] 传递到加密 API(通过内存流等)
  3. 从加密流中获取字节并将结果编码为 Base64

解密(做相反的事情)

  1. 使用 Convert.FromBase64String(base64EncodedEncryptedValue) 将 base64 编码字符串转换为字节
  2. 将该字节数组传递到上面的解密函数中

【讨论】:

  • 嘿 :) 这正是我正在做的。我将使用解密代码进行更新,以便您查看它,我可能做错了什么哈哈。
  • 好酷!我会试一试的!我会尽快告诉你这是否可行。
  • 实际上,我更喜欢返回 SecureString.or byte[]
  • 我注意到您没有将密钥和初始化向量传递给 CreateDecryptor,这不是必需的吗?
  • 所以我刚刚完成了我的流的重构,我得到了同样的东西,当解码 base64 字符串时,它是原始的 aes 加密字符串,解密该字符串给了我一堆垃圾:(
【解决方案2】:

试试:

encryptedBytes2 = Encoding.ASCII.GetBytes(encryptedText);

根据您的评论。字节就是那个字节,因此为了解密密文,您需要撤消您所做的任何编码或一系列编码。

如果你真的想从 Encrypted Bytes -> Base64String -> ASCII string -> 解密那个 ASCII 字符串?您需要对 ascii 字符串进行 base64 解码,然后使用

将该字符串转换为字节
Encoding.ASCII.GetBytes(yourdecodedstring); 

请注意,base 64 解码与使用 Convert.FromBase84String 不同。

【讨论】:

  • 这将破坏我试图实现的目的,即将 AES 编码为 base64 字符串,然后将 base64 解码为 AES 加密字符串,然后解密。
  • So Encrypted Bytes -> Base64String -> ASCII string -> 然后解密那个 ASCII 字符串?
  • 是的 :) 但无论出于何种原因,当我得到解密字符串的最后一步时,返回垃圾字符串而不是“foo bar”。
  • 为了解密,您需要传回完全相同的字节。您不能按照您的方式从 base64 转到 ASCII,然后再返回到 Base64。
  • 嗯,他的建议比我所做的要干净得多,没有错。您的回答帮助解决了我的解码问题。所以我希望你们两个都能得到好的答案和建议:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多