Files
bishe-STM32/Hardware/Crypto.c
T
2026-05-01 11:15:54 +08:00

100 lines
2.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 加密模块实现
* 使用AES-128-CBC + Base64编码
*/
#include "Crypto.h"
#include "aes.h"
#include "base64.h"
#include <string.h>
// ⚠️ 重要:密钥和IV必须与服务器端完全一致!
// AES-128密钥(16字节)
static const uint8_t AES_KEY[16] = {
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
};
// 初始化向量(16字节)
static const uint8_t AES_IV[16] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
static struct AES_ctx aes_ctx;
void Crypto_Init(void)
{
// 初始化AES上下文(使用CBC模式)
AES_init_ctx_iv(&aes_ctx, AES_KEY, AES_IV);
}
/**
* @brief PKCS#7填充
* 将数据填充到16字节的倍数
*/
static uint32_t pkcs7_pad(uint8_t* data, uint32_t data_len, uint32_t buffer_size)
{
// 计算需要填充的字节数
uint32_t padding_len = 16 - (data_len % 16);
// 检查缓冲区是否足够
if (data_len + padding_len > buffer_size) {
return 0; // 缓冲区不足
}
// 填充(PKCS#7标准)
uint32_t i;
for (i = 0; i < padding_len; i++) {
data[data_len + i] = (uint8_t)padding_len;
}
return data_len + padding_len;
}
uint32_t Crypto_EncryptJSON(const char* json_data, char* encrypted_output)
{
uint32_t json_len = strlen(json_data);
uint8_t buffer[512]; // 临时缓冲区
// 1. 复制JSON数据到缓冲区
if (json_len > sizeof(buffer) - 16) {
return 0; // 数据太长
}
memcpy(buffer, json_data, json_len);
// 2. PKCS#7填充到16字节的倍数
uint32_t padded_len = pkcs7_pad(buffer, json_len, sizeof(buffer));
if (padded_len == 0) {
return 0; // 填充失败
}
// 3. 手动实现标准CBC加密(绕过aes.c的bug)
struct AES_ctx ctx;
uint8_t iv[16];
uint32_t i, j;
// 初始化密钥和IV
AES_init_ctx(&ctx, AES_KEY);
memcpy(iv, AES_IV, 16);
// CBC加密:每个块先XOR IV,再加密,然后用密文更新IV
for (i = 0; i < padded_len; i += 16) {
// XOR with IV
for (j = 0; j < 16; j++) {
buffer[i + j] ^= iv[j];
}
// AES加密单个块
AES_ECB_encrypt(&ctx, &buffer[i]);
// 更新IV为当前密文块
memcpy(iv, &buffer[i], 16);
}
// 4. Base64编码
uint32_t encoded_len = base64_encode(buffer, padded_len, encrypted_output);
return encoded_len;
}