我正在尝试为AES 256加密创建一个处理程序类,并且我发现为每种加密使用不同的IV并将其放在字节数组的开头显然是安全的。所以我尝试添加它,但它无法正确获取。这是我的代码:
using System;
using System.Text;
using System.IO;
using System.Security.Cryptography;
namespace EncryptionTest
{
public class Aes256Handler
{
private byte[] key;
public Aes256Handler(byte[] key)
{
this.key = key;
}
public string EncryptString(string plaintext)
{
return Encoding.UTF8.GetString(Encrypt(Encoding.UTF8.GetBytes(plaintext)));
}
public string DecryptString(string encryptedtext)
{
return Encoding.UTF8.GetString(Decrypt(Encoding.UTF8.GetBytes(encryptedtext)));
}
public byte[] Encrypt(byte[] bytes)
{
if (bytes == null || bytes.Length < 1)
{
throw new ArgumentException("Invalid bytes");
}
if (key == null || key.Length < 1)
{
throw new InvalidOperationException("Invalid encryption settings");
}
byte[] encrypted;
try
{
using (Aes aes = Aes.Create())
{
aes.Mode = CipherMode.CBC;
aes.Key = key;
aes.KeySize = 256;
aes.BlockSize = 128;
Util.PrintByteArray(aes.IV);
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
using (MemoryStream ms = new MemoryStream())
{
ms.Write(aes.IV, 0, aes.IV.Length);
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
cs.Write(bytes, 0, bytes.Length);
cs.FlushFinalBlock();
}
encrypted = ms.ToArray();
}
}
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
throw new InvalidOperationException("Unable to encrypt data");
}
return encrypted;
}
public byte[] Decrypt(byte[] bytes)
{
if (bytes == null || bytes.Length < 1)
{
throw new ArgumentException("Invalid bytes");
}
if (key == null || key.Length < 1)
{
throw new InvalidOperationException("Invalid encryption settings");
}
byte[] decrypted;
try
{
using (Aes aes = Aes.Create())
{
aes.Mode = CipherMode.CBC;
aes.Key = key;
aes.KeySize = 256;
aes.BlockSize = 128;
byte[] iv = new byte[16];
MemoryStream ms = new MemoryStream(bytes);
ms.Read(iv, 0, iv.Length);
Util.PrintByteArray(iv);
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, iv);
using (ms)
{
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
using (BinaryReader br = new BinaryReader(cs))
{
decrypted = new byte[iv.Length];
br.Read(decrypted, 0, decrypted.Length - iv.Length);
}
}
decrypted = ms.ToArray();
}
}
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
throw new InvalidOperationException("Unable to decrypt data");
}
return decrypted;
}
}
}
输出:
Plain text: Hello World!
198 66 49 215 139 95 165 131 201 119 136 16 45 170 140 70
Encrypted text: �B1_���w�-��F?�����8#*�����
239 191 189 66 49 215 139 95 239 191 189 239 191 189 239 191
Decrypted text: �B1_���w�-��F?�����8#*�����
对于我的问题的解决方案和其他建议将不胜感激。
答案 0 :(得分:1)
我提供了下面提供的代码的工作版本:
$user = $this->getUser();
$user->addRole('ROLE_ADMIN');
$this->get('fos_user.user_manager')->updateUser($user);
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->get('security.context')->setToken($token);
所做的主要更改是在处理加密的字节数组时使用Convert.ToBase64String和Convert.FromBase64String。我还删除了针对AES对象的不必要的参数声明,因为它只是设置默认值,并且我从解密方法中删除了不必要的解密= ms.ToArray()。
还有一点很重要,那就是在进行解密时,您想要获取读取的字节数。使用由于加密的块大小而增加的填充而没有修整解密的字节数组,您会发现由于填充而在该数组的结尾将为0。