Visual studio Arduino AES128加密-C#解密填充问题
我需要单向加密通信。arduino对消息进行加密,并通过串行发送到C#程序进行解密 用于加密的arduino代码如下所示:Visual studio Arduino AES128加密-C#解密填充问题,visual-studio,encryption,arduino,aes,badpaddingexception,Visual Studio,Encryption,Arduino,Aes,Badpaddingexception,我需要单向加密通信。arduino对消息进行加密,并通过串行发送到C#程序进行解密 用于加密的arduino代码如下所示: #include <Crypto.h> #include <base64.hpp> #define BLOCK_SIZE 16 uint8_t key[BLOCK_SIZE] = { 1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7 }; uint8_t iv[BLOCK_SIZE] = { 7,6,5,4,3,2,1,9,8,7,6,
#include <Crypto.h>
#include <base64.hpp>
#define BLOCK_SIZE 16
uint8_t key[BLOCK_SIZE] = { 1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7 };
uint8_t iv[BLOCK_SIZE] = { 7,6,5,4,3,2,1,9,8,7,6,5,4,3,2,1 };
void bufferSize(char* text, int &length)
{
int i = strlen(text);
int buf = round(i / BLOCK_SIZE) * BLOCK_SIZE;
length = (buf <= i) ? buf + BLOCK_SIZE : length = buf;
}
void encrypt(char* plain_text, char* output, int length)
{
byte enciphered[length];
AES aesEncryptor(key, iv, AES::AES_MODE_128, AES::CIPHER_ENCRYPT);
aesEncryptor.process((uint8_t*)plain_text, enciphered, length);
int encrypted_size = sizeof(enciphered);
char encoded[encrypted_size];
encode_base64(enciphered, encrypted_size, (unsigned char*)encoded);
strcpy(output, encoded);
}
触发条件发生后,我收到一条错误消息:
System.Security.Cryptography.cryptographyException:“填充无效,无法删除。”
如果我认为正确的话,uint8_t(Arduino)与字节[](Visual Studio C#)相同,或者错误在其他地方吗?这里有一些错误
- Arduino:你应该每次随机生成一个IV,并随信息一起发送
- Arduino:你在整数表达式上使用
,这简直是浪费。删除单词round
不会改变任何答案(但它将删除浮点数学,并可能避免打开芯片的浮点部分,从而节省电源)round
- Arduino:您正在制作一个与输入大小相同的base64输出缓冲区(
)。Base64增长了4/3(encoded
),因此您正在进行缓冲区溢出。要么使缓冲区变大,要么简单地将things和base64直接编码到(size+2)/3*4
。输出
- 侧重点:您不接受
输出的边界。希望足够大
- 侧重点:您不接受
- C#::(一旦你让Arduino发送信息,你需要阅读每条信息的IV)
- C#:加密机和解密机各保存一次。每次手术后都需要重建(以恢复静脉注射)
- 两者都有:硬编码密钥几乎没有安全性。您将希望获取随机会话密钥。(ECDH密钥协议/PC发送RSA公钥,Arduino生成随机AES密钥,用RSA/etc加密后发送回)
pArfBo2HLU9+DXGhFPJDFg=
当您可以从cryptii.com和Arduino上的加密代码中得到相同的答案时,您可以继续使用解密逻辑(然后是random IV)
FWIW,加密序列对我来说没有多大意义。没有不受信任的分支,你可以在6英尺的电缆上轻松监控MITM…你说得对,问题在Arduino一侧,现在已经用你提供的数据进行了测试。主要目标是“锁定”arduino的一个软件,因为软件比arduino的硬件贵得多,我会阻止中国的复印机制造和我相同的设备并使用我的软件。老实说,我不认为中国的中型复印机公司会花费太多的超级计算机CPU时间来破解我的加密以接收kays并将其编程为他的arduino复制了硬件。
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.IO.Ports;
using System.Security.Cryptography;
namespace BaseReadSerial
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string[] ports = SerialPort.GetPortNames();
cBoxComPort.Items.AddRange(ports);
}
private void groupBox1_Enter(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
try
{
serialPort1.PortName = cBoxComPort.Text;
serialPort1.DtrEnable = true;
serialPort1.ReadTimeout = 5000;
serialPort1.WriteTimeout = 500;
serialPort1.Open();
lblStatusCom.Text = "On";
lblMessage.Text = "I am on!";
}
catch(Exception err)
{
MessageBox.Show(err.Message,"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
lblStatusCom.Text = "Off";
}
}
private void button2_Click(object sender, EventArgs e)
{
if(serialPort1.IsOpen)
{
//string mgs1 = serialPort1.ReadLine();
string mgs1 = "jEYGnz3TYm+aWveh8wNATw==";
serialPort1.Close();
lblStatusCom.Text = "Off";
string base64Decoded;
byte[] data = System.Convert.FromBase64String(mgs1);
base64Decoded = System.Text.ASCIIEncoding.ASCII.GetString(data);
//Start
var str = base64Decoded;
var aes = new SimpleAES();
var encryptStr = aes.Encrypt(str);
var decryptStr = aes.Decrypt(mgs1);
//End
lblMessage.Text = decryptStr;
}
}
private void label1_Click(object sender, EventArgs e)
{
Text = "Off";
}
private void lblStatusCom_Click(object sender, EventArgs e)
{
}
private void cBoxComPort_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
}
private void lblMessage_Click(object sender, EventArgs e)
{
}
}
public class SimpleAES
{
private byte[] key = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7 };
private byte[] vector = { 7, 6, 5, 4, 3, 2, 1, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
private readonly ICryptoTransform encryptor;
private readonly ICryptoTransform decryptor;
private readonly UTF8Encoding encoder;
public SimpleAES()
{
var rm = new RijndaelManaged();
encryptor = rm.CreateEncryptor(key, vector);
decryptor = rm.CreateDecryptor(key, vector);
encoder = new UTF8Encoding();
}
public string Encrypt(string unencrypted)
{
return Convert.ToBase64String(Encrypt(encoder.GetBytes(unencrypted)));
}
public string Decrypt(string encrypted)
{
return encoder.GetString(Decrypt(Convert.FromBase64String(encrypted)));
}
public byte[] Encrypt(byte[] buffer)
{
return Transform(buffer, encryptor);
}
public byte[] Decrypt(byte[] buffer)
{
return Transform(buffer, decryptor);
}
protected byte[] Transform(byte[] buffer, ICryptoTransform transform)
{
using (var stream = new MemoryStream())
{
using (var cs = new CryptoStream(stream, transform, CryptoStreamMode.Write))
{
cs.Write(buffer, 0, buffer.Length);
}
return stream.ToArray();
}
}
}
}