在C#UTF8之前的有效载荷垃圾字节到AES到Base64的转换

问题描述:

我一直试图在方法中使用AES加密和解密UTF-8字符串,然后将其作为Base64字符串返回,以实现正确的IV练习。使用this问题作为参考,我已将生成的IV预加载到Base64转换之前的字节数组中。我遇到了一个问题,解密方法返回的UTF-8字符串只有50个字符的随机垃圾(加密工件?)。我不认为这个问题与加密有关,因为解密方法会一直返回加密的字符串。我认为问题在于其他转换步骤之一,但我无法查看这可能来自哪里。任何帮助将不胜感激。在C#UTF8之前的有效载荷垃圾字节到AES到Base64的转换

加密方法

public static string EncryptString(string input, string key) 
    { 
     using (var aes = new AesCryptoServiceProvider()) 
     { 

      aes.Key = System.Convert.FromBase64String(key); 
      aes.Mode = CipherMode.CBC; 
      aes.Padding = PaddingMode.PKCS7; 

      byte[] rawData = Encoding.UTF8.GetBytes(input); 
      // IV is the 16 byte AES Initialization Vector 
      aes.GenerateIV(); 

      using (var encryptor = aes.CreateEncryptor(aes.Key, aes.IV)) 
      { 
       using (var ms = new MemoryStream()) 
       { 
        ms.Write(aes.IV, 0, aes.IV.Length); // aes.IV.Length should be 16 
        using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) 
        { 
         cs.Write(rawData, 0, rawData.Length); 
         cs.FlushFinalBlock(); 
        } 
        byte[] encryptedData = ms.ToArray(); 

        // this will hold the IV prepended to the encrypted data 
        byte[] output = new byte[aes.IV.Length + encryptedData.Length]; 

        Array.Copy(aes.IV, output, aes.IV.Length); // save the iv 
        Array.Copy(encryptedData, 0, output, aes.IV.Length, encryptedData.Length); // save the data 

        // now encode the whole thing as base 64 
        return System.Convert.ToBase64String(output); 

       } 
      } 

     } 

    } 

解密方法

public static string DecryptString(string input, string key) 
    { 

     using (var aes = new AesCryptoServiceProvider()) 
     { 
      aes.Key = Convert.FromBase64String(key); 
      aes.Mode = CipherMode.CBC; 
      aes.Padding = PaddingMode.PKCS7; 

      byte[] rawData = Convert.FromBase64String(input); 
      byte[] IV = new byte[16]; // aes.IV.Length should be 16 

      Array.Copy(rawData, IV, IV.Length); 
      using (var ms = new MemoryStream()) 
      { 
       using (var cs = new CryptoStream(ms, aes.CreateDecryptor(aes.Key, IV), CryptoStreamMode.Write)) 
       { 
        using (var binaryWriter = new BinaryWriter(cs)) 
        { 
         binaryWriter.Write(rawData,IV.Length ,rawData.Length - IV.Length); 
        } 
       } 
       return Encoding.UTF8.GetString(ms.ToArray()); 
      } 
     } 
    } 

我的测试

static void Main(string[] args) 
    { 
     string payload = "My super secret string"; 
     string key = "tR4mPn7mBQ8G6HWusyFnGk/gqdd/enWiUTr7YbhNrJg="; 

     Console.WriteLine(payload); 
     Console.WriteLine(key); 

     Console.WriteLine(""); 
     string encrypted = EncryptString(payload, key); 
     Console.WriteLine(encrypted); 

     Console.WriteLine(""); 
     string decrypted = DecryptString(encrypted, key); 
     Console.WriteLine(decrypted); 

     Console.WriteLine(decrypted.Length.ToString() + " " + encrypted.Length.ToString()); 

     Console.ReadKey(); 

    } 

编辑补充 - 这是输出的一个例子:

XQ = F] d我的超级秘密串

+0

检查输出为十六进制,你会看到这个问题,Base64是电脑,而不是人类。 – zaph

您在EncryptString写四输出两次?首先你有:

ms.Write(aes.IV, 0, aes.IV.Length); // aes.IV.Length should be 16 

这是encryptedData的开头。你那么IV和encryptedData(其中已经包含了IV)复制到一个新的字节数组:

// this will hold the IV prepended to the encrypted data 
byte[] output = new byte[aes.IV.Length + encryptedData.Length]; 

Array.Copy(aes.IV, output, aes.IV.Length); // save the iv 
Array.Copy(encryptedData, 0, output, aes.IV.Length, encryptedData.Length); // save the data 

静脉输液的翻倍是什么原因造成的额外的字节。

您不需要进行第二次复制。只是转换encryptedData直接底座64返回:

return System.Convert.ToBase64String(encryptedData); 
+0

这是正确的。我认为这是一个简单的错误。我疲惫的周五眼睛无法捕捉它。 –