- pem 格式公钥私钥读取解析
- 公钥 私钥 pem 格式加解密示例
- 根据私钥 pem 生成 模数和指数 N E D
- 生成 模数和指数 N E D 的公钥私钥
- N E D 导出 pem 格式
#include <SylixOS.h>
#include <stdio.h>
#include <crypto.h>
#include <mbedtls/ssl.h>
#include <mbedtls/platform.h>
#include <mbedtls/entropy.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/base64.h>
#include "libcrypto.h"
#define CRYPTO_TEST_EN (1) /* 测试模块开关宏 */
#include <crypto_test.h>
#define ROUND_UP(x, align) (size_t)(((size_t)(x) + (align - 1)) & ~(align - 1))
void printhex(char *name, UINT8 *data, size_t size);
/**
公钥由模数 N 和公钥指数 E 组成,通常以如下形式表示:
[ (N, E) ]
私钥则包含模数 N、私钥指数 D,以及可能还包括原始素数 p 和 q,以防需要重新计算其他参数。
私钥通常以如下形式表示:
[ (N, D, p, q) ]
*/
#define BUFFER_SIZE 256
/**
* 使用公钥私钥验证加密数据
*/
INT test_rsa_encry(void)
{
int ret;
mbedtls_pk_context priv_key, pub_key;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_rsa_context *rsa;
unsigned char encrypted[BUFFER_SIZE], decrypted[BUFFER_SIZE];
unsigned char *input = "hello world! \r\n";
size_t olen, ilen = strlen(input);
// const char *pers = "rsa_encrypt_decrypt_example";
const char *pers = "rsa_key_generation";
mbedtls_pk_init(&priv_key);
mbedtls_pk_init(&pub_key);
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&ctr_drbg);
// 1. 加载RSA私钥和公钥
ret = mbedtls_pk_parse_keyfile(&priv_key, "./prikey.txt", NULL);
if (ret != 0) {
printf("Failed to parse private key file: -0x%04x\n", -ret);
goto exit;
}
ret = mbedtls_pk_parse_public_keyfile(&pub_key, "./pubkey.txt");
if (ret != 0) {
printf("Failed to parse public key file: -0x%04x\n", -ret);
goto exit;
}
mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *)pers, strlen(pers));
// 3. 使用私/公钥加密消息
// ret = mbedtls_rsa_pkcs1_encrypt(mbedtls_pk_rsa(priv_key), mbedtls_ctr_drbg_random, &ctr_drbg, MBEDTLS_RSA_PRIVATE, ilen, input, encrypted);
ret = mbedtls_rsa_pkcs1_encrypt(mbedtls_pk_rsa(pub_key), mbedtls_ctr_drbg_random, &ctr_drbg, MBEDTLS_RSA_PUBLIC, ilen, input, encrypted);
if (ret != 0) {
printf("Failed to encrypt text: -0x%04x\n", -ret);
goto exit;
}
printhex("encrypted", encrypted, sizeof(encrypted));
// 4. 使用公/私钥解密消息
olen = BUFFER_SIZE;
// ret = mbedtls_rsa_pkcs1_decrypt(mbedtls_pk_rsa(pub_key), mbedtls_ctr_drbg_random, &ctr_drbg, MBEDTLS_RSA_PUBLIC, &olen, encrypted, decrypted, BUFFER_SIZE);
ret = mbedtls_rsa_pkcs1_decrypt(mbedtls_pk_rsa(priv_key), mbedtls_ctr_drbg_random, &ctr_drbg, MBEDTLS_RSA_PRIVATE, &olen, encrypted, decrypted, BUFFER_SIZE);
if (ret != 0) {
printf("Failed to decrypt text: -0x%04x\n", -ret);
goto exit;
}
printf("encode data size: %d \n", olen);
decrypted[olen] = '\0'; // Add null terminator for printing as a string
printf("Decrypted message: %s\n", decrypted);
exit:
mbedtls_pk_free(&priv_key);
mbedtls_pk_free(&pub_key);
mbedtls_entropy_free(&entropy);
mbedtls_ctr_drbg_free(&ctr_drbg);
return ret;
}
/**
* 将 pem 格式的私钥 转换成对应的 rsa (N E D)
*/
INT test_pem_to_rsa(void)
{
int ret;
mbedtls_pk_context pk;
mbedtls_rsa_context *rsa;
unsigned char *p, *end;
size_t len;
mbedtls_pk_init(&pk);
// 1. 加载PEM格式的私钥文件
ret = mbedtls_pk_parse_keyfile(&pk, "./prikey.txt", NULL);
if (ret != 0) {
printf("Failed to parse private key file: -0x%04x\n", -ret);
return -1;
}
// 2. 确保解析出的密钥是RSA类型
if (mbedtls_pk_get_type(&pk) != MBEDTLS_PK_RSA) {
printf("Private key is not an RSA key.\n");
return -1;
}
// 3. 获取RSA上下文
rsa = mbedtls_pk_rsa(pk);
// 4. 解析 N、D、E 参数
const mbedtls_mpi *N = &rsa->N;
const mbedtls_mpi *E = &rsa->E;
const mbedtls_mpi *D = &rsa->D;
printf("E: %zu bits, 8 algin: %zu, n: %zu \n", mbedtls_mpi_bitlen(E), ROUND_UP(mbedtls_mpi_bitlen(E), 8), E->n);
printf("N: %zu bits, 8 algin: %zu, n: %zu \n", mbedtls_mpi_bitlen(N), ROUND_UP(mbedtls_mpi_bitlen(N), 8), N->n);
printf("D: %zu bits, 8 algin: %zu, n: %zu \n", mbedtls_mpi_bitlen(D), ROUND_UP(mbedtls_mpi_bitlen(D), 8), D->n);
printhex("E", (UINT8 *)E->p, ROUND_UP(mbedtls_mpi_bitlen(E), 8)/8);
printhex("N", (UINT8 *)N->p, ROUND_UP(mbedtls_mpi_bitlen(N), 8)/8);
printhex("D", (UINT8 *)D->p, ROUND_UP(mbedtls_mpi_bitlen(D), 8)/8);
// 清理资源
mbedtls_pk_free(&pk);
return 0;
}
/**
* 写文件
*/
int test_write_to_file(char *filename, char *buff, int size)
{
int fd = open(filename, O_RDWR | O_CREAT);
if (fd < 0) {
printf("open file %s failed! \n", filename);
return -1;
}
if (write(fd, buff, size) < 0) {
printf("write file %s failed! \n", filename);
return -1;
}
close(fd);
return 0;
}
#define MAX_PUBKEY_PEM_LEN 1024
#define MAX_PRIKEY_PEM_LEN 2048
/**
* 将 rsa (N E D) 格式 导出 pem 格式的公私钥
*/
INT test_export_rsa_pem(mbedtls_rsa_context *rsa)
{
mbedtls_pk_context pk;
unsigned char pubkey_pem[MAX_PUBKEY_PEM_LEN];
unsigned char prikey_pem[MAX_PRIKEY_PEM_LEN];
int ret;
// 初始化pk上下文
mbedtls_pk_init(&pk);
// 设置 PK 上下文为 RSA
mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA));
// 获取 PK 上下文的 RSA 字段并设置 RSA 上下文
mbedtls_rsa_copy(mbedtls_pk_rsa(pk), rsa);
// 写入PEM公钥字符串
ret = mbedtls_pk_write_pubkey_pem(&pk, pubkey_pem, MAX_PUBKEY_PEM_LEN);
if (ret != 0) {
printf("Error writing PEM public key: -0x%04x\n", -ret);
return -1;
}
// 打印PEM公钥字符串
printf("PEM Public Key:\n%s\n", pubkey_pem);
// 导出私钥
ret = mbedtls_pk_write_key_pem(&pk, prikey_pem, MAX_PRIKEY_PEM_LEN);
if (ret != 0) {
printf("Error writing PEM private key: -0x%04x\n", -ret);
return -1;
}
printf("PEM Private Key:\n%s\n", prikey_pem);
// 导出文件
test_write_to_file("./pubkey.txt", pubkey_pem, strlen(pubkey_pem));
test_write_to_file("./prikey.txt", prikey_pem, strlen(prikey_pem));
// 读取验证
if(test_pem_to_rsa() < 0) {
printf("check failed! \n");
}
// 清理资源
mbedtls_pk_free(&pk);
return 0;
}
// #define KEY_BITS 2048 // 生成的RSA密钥位数,可以根据需要调整
#define KEY_BITS 4096 // 生成的RSA密钥位数,可以根据需要调整
/**
* 生成 N E D 模数和指数
*/
int test_rsa_gen_N_E_D(void)
{
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_rsa_context rsa;
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&ctr_drbg);
// 为熵源和DRBG提供种子
const char personalization[] = "rsa_key_generation";
if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
(const unsigned char *) personalization,
sizeof(personalization)) != 0) {
printf("Failed to seed DRBG.\n");
return -1;
}
mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V15, 0);
// 生成新的RSA公私钥对
if (mbedtls_rsa_gen_key(&rsa, mbedtls_ctr_drbg_random, &ctr_drbg, KEY_BITS,
65537) != 0) {
printf("Failed to generate RSA key pair.\n");
return -1;
}
// 获取模数N和指数E
const mbedtls_mpi *N = &rsa.N;
const mbedtls_mpi *E = &rsa.E;
const mbedtls_mpi *D = &rsa.D;
printf("E: %zu bits, 8 algin: %zu, n: %zu \n", mbedtls_mpi_bitlen(E), ROUND_UP(mbedtls_mpi_bitlen(E), 8), E->n);
printf("N: %zu bits, 8 algin: %zu, n: %zu \n", mbedtls_mpi_bitlen(N), ROUND_UP(mbedtls_mpi_bitlen(N), 8), N->n);
printf("D: %zu bits, 8 algin: %zu, n: %zu \n", mbedtls_mpi_bitlen(D), ROUND_UP(mbedtls_mpi_bitlen(D), 8), D->n);
printhex("E", (UINT8 *)E->p, ROUND_UP(mbedtls_mpi_bitlen(E), 8)/8);
printhex("N", (UINT8 *)N->p, ROUND_UP(mbedtls_mpi_bitlen(N), 8)/8);
printhex("D", (UINT8 *)D->p, ROUND_UP(mbedtls_mpi_bitlen(D), 8)/8);
// 导出 pem 格式
test_export_rsa_pem(&rsa);
mbedtls_rsa_free(&rsa);
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
return 0;
}
/**
* rsa (根据 N E D 加解密测试) 硬件加速测试
*/
INT test_N_E_D_encry_hw(void)
{
int fd;
UINT32 uiDataSize = 4096 / 8;
UINT8 *pucHardOut = NULL;
UINT8 *pucHardOut1 = NULL;
UINT8 *pucSignIn = NULL;
UINT8 *pucETmp = NULL;
CRYPTO_RSA_KEY rsaKey;
fd = open("/dev/crypto0", O_RDWR);
if (fd < 0) {
printf("open /dev/crypto0 failed, ecode: %d\n", errno);
return -1;
}
pucHardOut = (UINT8 *)sys_malloc_align(uiDataSize*3, CONFIG_SYS_CACHELINE_SIZE);
if (!pucHardOut) {
printf("%s, %d: malloc %u error!\n", __func__, __LINE__, uiDataSize);
goto __exit;
}
lib_memset(pucHardOut, 0x0, uiDataSize*3);
pucHardOut1 = pucHardOut + uiDataSize;
pucETmp = pucHardOut + uiDataSize*2;
pucSignIn = (UINT8 *)sys_malloc_align(512, CONFIG_SYS_CACHELINE_SIZE);
if (!pucSignIn) {
printf("%s, %d: malloc %u error!\n", __func__, __LINE__, uiDataSize);
goto __free_hardout;
}
lib_memset(pucSignIn, 0x0, 512);
pucSignIn[0] = 0xAA;
pucSignIn[1] = 0xBB;
pucSignIn[2] = 0xCC;
lib_memset(&rsaKey, 0x00, sizeof(rsaKey));
/* (N, D) 私钥加密 */
rsaKey.uiAlgo = CRYPTO_RSA4096;
rsaKey.puiN = (UINT32 *)_G_cpucRsa4096_N;
rsaKey.puiE = (UINT32 *)_G_cpucRsa4096_D;
printhex("sign in", pucSignIn, 512);
if (crypto_rsa_verify(fd, &rsaKey, pucSignIn, pucHardOut)) {
printf("crypto_rsa_verify error! errcode: %d.\n", errno);
goto __free_signin;
}
printhex("sign out", pucHardOut, 512);
lib_memset(&rsaKey, 0x00, sizeof(rsaKey));
lib_memcpy(pucETmp, _G_cpucRsa4096_E, sizeof(_G_cpucRsa4096_E));
/* (N, E) 公钥解密 */
rsaKey.uiAlgo = CRYPTO_RSA4096;
rsaKey.puiN = (UINT32 *)_G_cpucRsa4096_N;
rsaKey.puiE = (UINT32 *)pucETmp;
if (crypto_rsa_verify(fd, &rsaKey, pucHardOut, pucHardOut1)) {
printf("crypto_rsa_verify error\n");
goto __free_signin;
}
printhex("verfiy out", pucHardOut1, 512);
if (lib_memcmp(pucHardOut1, pucSignIn, 512) == 0) {
printf("verfiy success!\n");
} else {
printf("verfiy failed!\n");
}
__free_signin:
sys_free(pucSignIn);
__free_hardout:
sys_free(pucHardOut);
__exit:
close(fd);
return 0;
}
INT main(int argc, char const *argv[])
{
test_rsa_gen_N_E_D();
// test_N_E_D_encry_hw(fd);
// test_rsa_encry();
return 0;
}
void printhex(char *name, UINT8 *data, size_t size)
{
int i = 0;
printf("\n%s:\n", name);
for (i = 0; i < size; i++) {
printf("%02x ", data[i]);
if (i % 16 == 15) {
printf("\n");
}
}
printf("\n");
}
标签:公钥,私钥,drbg,rsa,ret,模数,mbedtls,printf,pk
From: https://www.cnblogs.com/han-guang-xue/p/18122413