C#AES加密字节数组
我想加密字节数组。所以首先我试了一下C#AES加密字节数组,c#,encryption,cryptography,aes,C#,Encryption,Cryptography,Aes,我想加密字节数组。所以首先我试了一下 键=00000000000000000000 IV=00000000000000000000 输入数据=1EA0353A7D2947D8BBC6AD6FB52FCA84 类型=CBC 它计算了这个 加密输出=C5537C8EFFCC7E152C27831AFD383BA 然后我使用System.Security.Cryptography库并计算它。但它给了我不同的结果。你能帮我解决那种情况吗 代码 using System; using System
- 键=00000000000000000000
- IV=00000000000000000000
- 输入数据=1EA0353A7D2947D8BBC6AD6FB52FCA84
- 类型=CBC
- 加密输出=C5537C8EFFCC7E152C27831AFD383BA
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Security.Cryptography;
namespace DesfireCalculation
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
byte key_no = 0x00;
byte[] key = new byte[16] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
byte[] IV = new byte[16] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
byte[] rndB = new byte[16] { 0x1E,0xA0,0x35,0x3A,0x7D,0x29,0x47,0xD8,0xBB,0xC6,0xAD,0x6F,0xB5,0x2F,0xCA,0x84 };
private void Form1_Load(object sender, EventArgs e)
{
try
{
byte[] res=EncryptStringToBytes_Aes(BitConverter.ToString(rndB), key, IV);
string res_txt = BitConverter.ToString(res);
Console.WriteLine(res_txt);
}
catch (Exception ex)
{
Console.WriteLine("Error: {0}", ex.Message);
}
}
static byte[] EncryptStringToBytes_Aes(byte[] Data, byte[] Key, byte[] IV)
{
// Check arguments.
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
byte[] encrypted;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
aesAlg.Mode = CipherMode.CBC;
aesAlg.BlockSize = 128;
aesAlg.FeedbackSize = 128;
aesAlg.KeySize = 128;
// Create an encryptor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(Data);
}
encrypted = msEncrypt.ToArray();
}
}
}
// Return the encrypted bytes from the memory stream.
return encrypted;
}
}
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows.Forms;
使用System.IO;
使用System.Security.Cryptography;
命名空间计算
{
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
}
字节键_no=0x00;
字节[]键=新字节[16]{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
字节[]IV=新字节[16]{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
字节[]rndB=新字节[16]{0x1E、0xA0、0x35、0x3A、0x7D、0x29、0x47、0xD8、0xBB、0xC6、0xAD、0x6F、0xB5、0x2F、0xCA、0x84};
私有void Form1\u加载(对象发送方、事件参数e)
{
尝试
{
字节[]res=EncryptStringToBytes_Aes(位转换器.ToString(rndB),密钥,IV);
字符串res_txt=位转换器.ToString(res);
Console.WriteLine(res_-txt);
}
捕获(例外情况除外)
{
WriteLine(“错误:{0}”,例如Message);
}
}
静态字节[]EncryptStringToBytes_Aes(字节[]数据,字节[]密钥,字节[]IV)
{
//检查参数。
如果(Key==null | | Key.Length输入数据不同,因此结果也不同。
在站点上,您的明文是“C5537C8EFFCC7E152C27831AFD383BA
”,在代码中是
“B969FDFE56FD91FC9DE6F6F213B8FD1E
”网站声明:
Input Data (It will be padded with zeroes if necessary.)
填充在密码学中非常重要
因此,请确保您正在使用:
aes.Padding=PaddingMode.Zeros;
在这种情况下,如果没有它,您将获得更长的填充字节结果
编辑:对于实际情况,您可能应该使用默认值:PKCS#7。@Wimconen有很好的理由。请查看注释
代码的另一个问题是:在设置密钥和IV的大小之前,您正在设置它们。
这是错误的:
aesAlg.Key = Key;
aesAlg.IV = IV;
aesAlg.Mode = CipherMode.CBC;
aesAlg.BlockSize = 128;
aesAlg.FeedbackSize = 128;
aesAlg.KeySize = 128;
这是正确的顺序:
aesAlg.Mode = CipherMode.CBC;
aesAlg.KeySize = 128;
aesAlg.BlockSize = 128;
aesAlg.FeedbackSize = 128;
aesAlg.Padding = PaddingMode.Zeros;
aesAlg.Key = key;
aesAlg.IV = iv;
代码的另一个问题是您正在使用StreamWriter写入加密流:
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(Data);
}
StreamWriter可能会把一切都搞糟。它是为编写特定编码的文本而设计的
请检查下面的代码,了解我的实现是否适用于您的案例
public class AesCryptographyService
{
public byte[] Encrypt(byte[] data, byte[] key, byte[] iv)
{
using (var aes = Aes.Create())
{
aes.KeySize = 128;
aes.BlockSize = 128;
aes.Padding = PaddingMode.Zeros;
aes.Key = key;
aes.IV = iv;
using (var encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
{
return PerformCryptography(data, encryptor);
}
}
}
public byte[] Decrypt(byte[] data, byte[] key, byte[] iv)
{
using (var aes = Aes.Create())
{
aes.KeySize = 128;
aes.BlockSize = 128;
aes.Padding = PaddingMode.Zeros;
aes.Key = key;
aes.IV = iv;
using (var decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
{
return PerformCryptography(data, decryptor);
}
}
}
private byte[] PerformCryptography(byte[] data, ICryptoTransform cryptoTransform)
{
using (var ms = new MemoryStream())
using (var cryptoStream = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write))
{
cryptoStream.Write(data, 0, data.Length);
cryptoStream.FlushFinalBlock();
return ms.ToArray();
}
}
}
var key = new byte[16] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
var iv = new byte[16] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
var input = new byte[16] { 0x1E,0xA0,0x35,0x3A,0x7D,0x29,0x47,0xD8,0xBB,0xC6,0xAD,0x6F,0xB5,0x2F,0xCA,0x84 };
var crypto = new AesCryptographyService();
var encrypted = crypto.Encrypt(input, key, iv);
var str = BitConverter.ToString(encrypted).Replace("-", "");
Console.WriteLine(str);
它将输出结果:
C5537C8EFFFCC7E152C27831AFD383BA
与您正在引用的站点上的相同:
编辑:
我已更改了您的函数,因此它将输出正确的结果:
static byte[] EncryptStringToBytes_Aes(byte[] data, byte[] key, byte[] iv)
{
// Check arguments.
if (key == null || key.Length <= 0)
throw new ArgumentNullException("key");
if (iv == null || iv.Length <= 0)
throw new ArgumentNullException("iv");
byte[] encrypted;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Mode = CipherMode.CBC;
aesAlg.KeySize = 128;
aesAlg.BlockSize = 128;
aesAlg.FeedbackSize = 128;
aesAlg.Padding = PaddingMode.Zeros;
aesAlg.Key = key;
aesAlg.IV = iv;
// Create an encryptor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
csEncrypt.Write(data, 0, data.Length);
csEncrypt.FlushFinalBlock();
encrypted = msEncrypt.ToArray();
}
}
}
// Return the encrypted bytes from the memory stream.
return encrypted;
}
静态字节[]加密StringToBytes_Aes(字节[]数据,字节[]密钥,字节[]iv)
{
//检查参数。
如果(key==null | | key.Length为什么要将输入字节数组转换为字符串?@Magnus我在这里找到了它给出的示例A2E4E50D343BEA0A222B643A48E37644@Magnus我改为字节数组的函数。这解决了返回长度数据的长度问题。但它的答案与示例中的不同。@eocron感谢您的兴趣。您有不同的re吗sult every time?感谢您的关注和关注。我编辑了代码和示例。但是示例和我的代码仍然有不同的结果。+1很好的捕获。但是请注意,默认填充为PKCS#7有一个很好的原因:使用零填充,解密时您将得到额外的零,因为无法在一个时间区分零字节明文的结尾或由填充添加的结尾,除非您在加密前将自己的打包结构添加到明文。@wimconen是的。在答案中添加了您的建议。@BART我实现了代码,但在解密的字节[]中收到填充的零(我的数据是11字节,块大小是128):Original:0A0963657274206E616D65往返:0A0963657274206E616D65000000000如何避免