如何为Base64应用填充

当我使用四个字母的单词作为输入时,我有以下代码可以正常工作,例如“测试”。 当输入不是4的倍数时,它会失败例如“MyTest”。

Eexception:Base-64 char数组的长度无效。

质询

  1. 是否保证加密结果始终与Unicode字符串兼容(没有任何损失)。 如果是,我可以使用UTF编码而不是Base64? 在编码方面,UTF8 / UTF16和Base64之间有什么区别
  2. 如何输入填充以便我们得到正确的结果(解密后),即使输入不是4的倍数?

主要的PRGORAM

class Program { static void Main(string[] args) { string valid128BitString = "AAECAwQFBgcICQoLDA0ODw=="; string inputValue = "MyTest"; string keyValue = valid128BitString; byte[] byteValForString = Convert.FromBase64String(inputValue); EncryptResult result = Aes128Utility.EncryptData(byteValForString, keyValue); EncryptResult encyptedValue = new EncryptResult(); string resultingIV = "4uy34C9sqOC9rbV4GD8jrA=="; if (String.Equals(resultingIV,result.IV)) { int x = 0; } encyptedValue.IV = resultingIV; encyptedValue.EncryptedMsg = result.EncryptedMsg; string finalResult = Convert.ToBase64String(Aes128Utility.DecryptData(encyptedValue, keyValue)); Console.WriteLine(finalResult); if (String.Equals(inputValue, finalResult)) { Console.WriteLine("Match"); } else { Console.WriteLine("Differ"); } Console.ReadLine(); } } 

AES加密实用程序

 public static class Aes128Utility { private static byte[] key; public static EncryptResult EncryptData(byte[] rawData, string strKey) { EncryptResult result = null; if (key == null) { if (!String.IsNullOrEmpty(strKey)) { key = Convert.FromBase64String((strKey)); result = Encrypt(rawData); } } else { result = Encrypt(rawData); } return result; } public static byte[] DecryptData(EncryptResult encryptResult, string strKey) { byte[] origData = null; if (key == null) { if (!String.IsNullOrEmpty(strKey)) { key = Convert.FromBase64String(strKey); origData = Decrypt(Convert.FromBase64String(encryptResult.EncryptedMsg), Convert.FromBase64String(encryptResult.IV)); } } else { origData = Decrypt(Convert.FromBase64String(encryptResult.EncryptedMsg), Convert.FromBase64String(encryptResult.IV)); } return origData; } private static EncryptResult Encrypt(byte[] rawData) { using (AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider()) { aesProvider.Key = key; aesProvider.Mode = CipherMode.CBC; aesProvider.Padding = PaddingMode.PKCS7; aesProvider.IV = Convert.FromBase64String("4uy34C9sqOC9rbV4GD8jrA=="); using (MemoryStream memStream = new MemoryStream()) { CryptoStream encStream = new CryptoStream(memStream, aesProvider.CreateEncryptor(), CryptoStreamMode.Write); encStream.Write(rawData, 0, rawData.Length); encStream.FlushFinalBlock(); EncryptResult encResult = new EncryptResult(); encResult.EncryptedMsg = Convert.ToBase64String(memStream.ToArray()); encResult.IV = Convert.ToBase64String(aesProvider.IV); return encResult; } } } private static byte[] Decrypt(byte[] encryptedMsg, byte[] iv) { using (AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider()) { aesProvider.Key = key; aesProvider.IV = iv; aesProvider.Mode = CipherMode.CBC; aesProvider.Padding = PaddingMode.PKCS7; using (MemoryStream memStream = new MemoryStream()) { CryptoStream decStream = new CryptoStream(memStream, aesProvider.CreateDecryptor(), CryptoStreamMode.Write); decStream.Write(encryptedMsg, 0, encryptedMsg.Length); decStream.FlushFinalBlock(); return memStream.ToArray(); } } } } 

DTO

 public class EncryptResult { public string EncryptedMsg { get; set; } public string IV { get; set; } } 

参考文献

  1. 如何使用FromBase64String创建长度为16的byte []
  2. 使用AesCryptoServiceProvider获取不正确的解密值

Base64是一种将二进制值表示为文本的方法,这样您就不会与新行的\x0A或字符串终止符的\0等公共控制代码冲突。 它不适用于将键入的文本转换为二进制文件。

以下是您应该如何传递文本并将其取回。 您可以用您想要的任何编码替换UTF8 ,但您需要确保Encoding.Whatever.GetBytesEncoding.Whatever.GetBytes相同。

 class Program { static void Main(string[] args) { string valid128BitString = "AAECAwQFBgcICQoLDA0ODw=="; string inputValue = "MyTest"; string keyValue = valid128BitString; //Turns our text in to binary data byte[] byteValForString = Encoding.UTF8.GetBytes(inputValue); EncryptResult result = Aes128Utility.EncryptData(byteValForString, keyValue); EncryptResult encyptedValue = new EncryptResult(); //(Snip) encyptedValue.IV = resultingIV; encyptedValue.EncryptedMsg = result.EncryptedMsg; string finalResult = Encoding.UTF8.GetString(Aes128Utility.DecryptData(encyptedValue, keyValue)); Console.WriteLine(finalResult); if (String.Equals(inputValue, finalResult)) { Console.WriteLine("Match"); } else { Console.WriteLine("Differ"); } Console.ReadLine(); } } 

如果你正在加密,那么为我编码Base64不会添加任何有用的东西,而是会带来你遇到的问题。

至于填充,我看到的解决方案是创建一个新的byte [],它确实是4的倍数,并将源byte []复制到新的byte []。

所以,像这样:

  if (rawdata.Length % 16 !=0) { newSource = new byte[source.Length + 16 - source.Length % 16]; Array.Copy(source, newSource, source.Length); }