我需要单向加密通信。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,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);
}
加密的消息是:
jEYGnz3TYm+aWveh8wNATw==
明文消息是:
24051984
在 PC 端,我在 Visual Studio 中有下一个代码:
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();
}
}
}
}
触发条件发生后,我收到一条错误消息:
System.Security.Cryptography.CryptographicException: 'Padding is invalid and cannot be removed.'
如果我认为正确,uint8_t (Arduino) 与byte[] (Visual Studio C#) 相同,还是其他地方的错误?