#include <mbedtls/pk.h>
#include <mbedtls/rsa.h>
#include <mbedtls/pem.h>
#include <mbedtls/sha256.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/entropy.h>//环境安装参考https://blog.csdn.net/imba_wolf/article/details/122417540的教程
// #include <arduino_base64.hpp>//https://github.com/dojyorin/arduino_base64
void setup() {
Serial.begin(115200);
mbedtls_pk_context key;
mbedtls_rsa_context *rsa = NULL;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_pk_init(&key);
mbedtls_ctr_drbg_init(&ctr_drbg);
// 初始化随机数生成器
const char *personalization = "random_seed";
mbedtls_entropy_context entropy;
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *)personalization, strlen(personalization));
// 解析PEM格式的密钥字符串
const char *pemKey = R"(
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAuRxgd36cFdmebg79B6heLLsmvtLbUeLiGbn7RQ2B8D7nBqXP
0e0Kipf/VfA3Q1cDuz+YbauG+1RE+czXCfy4/ErGcmWP8dTwdzLIkfM2bcbNVamG
Fi95KFhd7kYNDLpCv1eVpJWShV3F9LsBjvdQ4E1NqG9wHq1aVX1gQjw4v4LPHlEr
1HHYL1bRuWE+66msw3PhGMZbk2TgSO9ecwsuWj1RB85CdOfxn2k4CKYrWAfBy+Lu
DvZ1qYScyCe5+C8aqQRBbxAY5ITukftkSSgNNAW9851bATKg0tr7h7r9eP/jiyk/
346q3zxFnXJpZSZBZT6KulYbU5cz1ZZE8VduRQIDAQABAoIBAFLvBcFDtkaL01FX
4cF2i4ra5ocEDULotYf1LUBIxviOFg+CZlOVMe3aH4mvL/M5nvBbk70+5iDgJm8M
eSN+WJqgHbzPB+i/EGU3GWlaX/5a3VANvYdfCZcr0BmaxOn44UK8yMyOPrEFzFTT
G+WjpFZ6C9r04nS8EgbPPzsto/cYrvJ/eACaqsy4w9EpYXJdvX3iV42m+yyYQzaW
jLYz/iLiO2XYCJE7gV9OLxxWCbXvooIOLc9P+d7jtav1LDw1aiflQ1Van+ajqLGO
NgnQcow8qa2lOK49ygoX4ChoLCbjZsRH/LT64ibZlwczcf/9s0RCkmxNcnPZ60Rz
CFqwrIECgYEA4AduMcfzaCrFA6HLAHGDGGkqLbh9bmB0MfMKMxFhZaSyn/iZhcUP
XxjdK5PfzE4utDE5RV+HlqwbDVgVgTpi0/FV4Bxa+yWT+ltrB4vOrDVQyC82hMWK
F87OL+cFzWHFvLd/FVaMPumeTefMa917T1mlsH026oJwliQlL9X2vlECgYEA04cg
0r55AJSApFABFA3NF2qO/BulbOFNfC2HiUIqOcih82iPjElq3iUcM2yoDAlCvOxr
06NnMDBVYVX+p7OeFMPbjM6Mi62lpa500IZCg+GlO21l7WCWPabmSo2Kg27I5ejl
owmP87rst2kcbs8TsvTuAuU4c3ghD6Td3jdSL7UCgYBmdH983MkA1q6LXq8MYN1n
iJD1n+4dUJdTUKdVe5ljdtMKPhNYDitdfm2HxHURZqANYIWkqG/GBKfKjoInO6B+
9VwkxlMFkMYANVbZeKLoNune41i3l+/zu2yok6sfpptcFz9TbuVs0ELJtjzTB9Oh
EoqoEFvRHB6JS7aGDgBuQQKBgDh/0muYBrf58nZxDCiwGwTTKIf8Vm5Dq6+sdZRb
AO5YQbHDTvxYq9vUK7ksn6I/Yv0VZSOtdKVxc4zBLHjcyC+htOXiUbYJVsJvW7JK
+j9BqSG7ccs6zkZ/aumk7sd2cuC+GYA30KR4XDwNLlQGqatWMrDBSxfEkYgdMEnn
muM1AoGBAMgafcagqkjYSOJvtZ+SAEMni1zrASLUKwVo9lmRz110gEmROicGcvV/
oHKdCdTsXi5oDQyFlqRlvN+yCbFRkRvCFlO03tkwU4yb2AKNPNf9UDoqB3q6etzc
y3/b5CSBY7YXdOtPeZovXvDafk/bhJa2a3Vh/XUn96tPSHkNMa5w
-----END RSA PRIVATE KEY-----
)";
const char *publickey = R"(
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuRxgd36cFdmebg79B6he
LLsmvtLbUeLiGbn7RQ2B8D7nBqXP0e0Kipf/VfA3Q1cDuz+YbauG+1RE+czXCfy4
/ErGcmWP8dTwdzLIkfM2bcbNVamGFi95KFhd7kYNDLpCv1eVpJWShV3F9LsBjvdQ
4E1NqG9wHq1aVX1gQjw4v4LPHlEr1HHYL1bRuWE+66msw3PhGMZbk2TgSO9ecwsu
Wj1RB85CdOfxn2k4CKYrWAfBy+LuDvZ1qYScyCe5+C8aqQRBbxAY5ITukftkSSgN
NAW9851bATKg0tr7h7r9eP/jiyk/346q3zxFnXJpZSZBZT6KulYbU5cz1ZZE8Vdu
RQIDAQAB
-----END PUBLIC KEY-----
)";
int ret = mbedtls_pk_parse_key(&key, (const unsigned char *)pemKey, strlen(pemKey) + 1, NULL, 0);
if (ret != 0) {
Serial.println("Failed to parse private key.");
Serial.println(ret);
while (1) {}//程序死锁防止跑飞 手动rst复位
}
// 计算SHA256哈希值
const char *data = "a=1"; //要签名的信息
unsigned char hash[32];
mbedtls_sha256((const unsigned char *)data, strlen(data), hash, 0);
// for (size_t i = 0; i <32; i++) {
// Serial.print(hash[i], HEX);//输出SHA256
// }
// 使用密钥对哈希值进行数字签名
unsigned char signature[256];
size_t signatureLen;
ret = mbedtls_pk_sign(&key, MBEDTLS_MD_SHA256, hash, sizeof(hash), signature, &signatureLen, mbedtls_ctr_drbg_random, &ctr_drbg);
if (ret != 0) {
Serial.println("Failed to sign the data.");
Serial.println(ret);
while (1) {}
}
// 打印签名结果
char hexString[5];
Serial.print("============= SignatureIS (in hex): ============= \n");
for (size_t i = 0; i < signatureLen; i++) {
// Serial.print(signature[i], HEX);
sprintf(hexString, "%02X", signature[i]);
Serial.print(hexString);//输出SHA256withRSA的16进制结果
}
Serial.println("\n==============================================\n\n");
// 打印签名的base64结果
// char base64signoutput[base64::encodeLength(sizeof(signature))];//制造一个长度仅为base生成长度一致的字符串
// base64::encode(signature,sizeof(signature), base64signoutput);
// Serial.println("SHA256withRSAsignIS:");
// Serial.println(base64signoutput);
// Serial.println("\n");
// 清理资源
mbedtls_pk_free(&key);
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
// 签名完成后的处理... ========================================================================================================
// 以下代码仅仅用到上文 1.公钥 2.signature 3.signatureLen
mbedtls_pk_context ctx_pk;
mbedtls_pk_init(&ctx_pk);
// Load the public key
if(0 != mbedtls_pk_parse_public_key(&ctx_pk, (uint8_t* )publickey, strlen(publickey)+1))
{
printf("Can't import public key\r\n") ;
}
// SHA-256 hash the data to be verified
unsigned char hash2[32];
const char *data_to_verify = "a=1"; //要验证的信息
mbedtls_sha256((const unsigned char *)data_to_verify, strlen(data_to_verify), hash2, 0);
// Verify the digital signature
if (mbedtls_pk_verify(&ctx_pk, MBEDTLS_MD_SHA256, hash2, sizeof(hash2), (const unsigned char *)signature, signatureLen) != 0) {
Serial.println("Signature verification failed.");
} else {
Serial.println("Signature verified successfully.");
}
// Clean up resources
mbedtls_pk_free(&ctx_pk);
// delay(1000);
}
void loop() {
}