公钥私钥和模数指数相互转换
- pem 格式公钥私钥读取解析
- 公钥 私钥 pem 格式加解密示例
- 根据私钥 pem 生成 模数和指数 N E D
- 生成 模数和指数 N E D 的公钥私钥
- N E D 导出 pem 格式
#include <stdio.h>
#include <string.h>
#include <rkcrypto.h>
#include <mbedtls/ssl.h>
#include <mbedtls/platform.h>
#include <mbedtls/entropy.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/base64.h>
#include <mbedtls/md.h>
#include <mbedtls/md_internal.h>
#include <mbedtls/pk.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);
// 加密数据块的长度取决于模长: RSA 模长通常是固定的大素数乘积(如 1024、2048 或 4096 位),对应的加密后数据块长度分别为 128、256 或 512 字节。
#define BUFFER_SIZE 128
/**
公钥由模数 N 和公钥指数 E 组成,通常以如下形式表示:
[ (N, E) ]
私钥则包含模数 N、私钥指数 D,以及可能还包括原始素数 p 和 q,以防需要重新计算其他参数。
私钥通常以如下形式表示:
[ (N, D, p, q) ]
*/
static int myrand( void *rng_state, unsigned char *output, size_t len )
{
size_t i;
if( rng_state != NULL )
rng_state = NULL;
// for( i = 0; i < len; ++i )
// output[i] = rand();
// return( 0 );
int fd = open("/dev/rng", O_RDONLY);
if (fd < 0) {
perror("open file failed \n");
return -1;
}
read(fd, output, len);
close(fd);
return (0);
}
/**
* 使用公钥私钥验证加密数据, 这里采用 rng 硬件模块
*/
INT test_rsa_encry_with_rkrng (void)
{
int ret;
mbedtls_pk_context priv_key, pub_key;
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_key_generation";
mbedtls_pk_init(&priv_key);
mbedtls_pk_init(&pub_key);
// 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;
}
// 3. 使用私/公钥加密消息
ret = mbedtls_rsa_pkcs1_encrypt(mbedtls_pk_rsa(pub_key), myrand, NULL, 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(priv_key), myrand, NULL, 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);
return ret;
}
/**
* 测试 RSA 签名验签, pkcs 接口
*/
INT test_rsa_sign_verify_pkcs(void)
{
int ret = -1;
const unsigned char sha256[32] = {
0x9b, 0xa8, 0x85, 0x0a, 0xa8, 0x2c, 0x21, 0x6a,
0x36, 0x89, 0xf8, 0x0f, 0x10, 0xa4, 0x0d, 0x01,
0x8b, 0x1c, 0xce, 0x7e, 0xe4, 0xa2, 0xc8, 0xa8,
0xa7, 0xff, 0x4d, 0x4b, 0x14, 0x1a, 0x67, 0xf0,
};
unsigned char rsa_ciphertext[512];
mbedtls_pk_context priv_key;
mbedtls_pk_context pub_key;
mbedtls_pk_init(&priv_key);
mbedtls_pk_init(&pub_key);
mbedtls_rsa_context *pri_rsa;
mbedtls_rsa_context *pub_rsa;
// 2. 加载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;
}
pri_rsa = mbedtls_pk_rsa(priv_key);
pub_rsa = mbedtls_pk_rsa(pub_key);
// 签名
if((ret = mbedtls_rsa_pkcs1_sign(pri_rsa, myrand, LW_NULL, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA256, 0,
sha256, rsa_ciphertext)) != 0 ) {
printf("pkcs1 sign failed, -0x%04x\n", -ret);
goto exit;
}
// 验签
if((ret = mbedtls_rsa_pkcs1_verify(pri_rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA256, 0,
sha256, rsa_ciphertext)) != 0 ) {
printf("pkcs1 verify failed, -0x%04x\n", -ret);
goto exit;
}
printf("sign and verify ok! \n");
ret = 0;
exit:
mbedtls_pk_free(&priv_key);
mbedtls_pk_free(&pub_key);
mbedtls_rsa_free(pri_rsa);
mbedtls_rsa_free(pub_rsa);
return ret;
}
/**
* 测试 RSA 签名验签 mbedtls 接口
*/
INT test_rsa_sign_verify_mbedtls(void)
{
int ret = 0;
// 1. Initialize entropy source and CTR_DRBG
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&ctr_drbg);
const char *pers = "rsa_key_generation";
if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
(const unsigned char *) pers, strlen(pers))) != 0) {
printf("Failed to initialize CTR_DRBG: -0x%04X\n", -ret);
goto exit;
}
mbedtls_pk_context priv_key;
mbedtls_pk_context pub_key;
mbedtls_pk_init(&priv_key);
mbedtls_pk_init(&pub_key);
// 2. 加载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;
}
// 3. Define the hash function to use for signing (e.g., SHA-256)
/*
Hash 长度根据算法确定
SHA-224: 224 bits (28 bytes)
SHA-256: 256 bits (32 bytes)
SHA-384: 384 bits (48 bytes)
SHA-512: 512 bits (64 bytes)
*/
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
// 4. Prepare the message to be signed
const unsigned char msg[] = "Example message to sign";
size_t msg_len = strlen((const char *) msg);
// 5. Compute the message digest
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
size_t hash_len;
hash_len = mbedtls_md_get_size(md_info);
printf("Hash length for %s: %u bytes\n", mbedtls_md_get_name(md_info), (unsigned) hash_len);
if ((ret = mbedtls_md(md_info, msg, msg_len, hash)) != 0) {
printf("Failed to compute message digest: -0x%04X\n", -ret);
goto exit;
}
// 6. Sign the message digest
unsigned char signature[MBEDTLS_MPI_MAX_SIZE]; // Buffer for the signature
size_t sig_len = sizeof(signature);
if ((ret = mbedtls_pk_sign(&priv_key, md_info->type, hash, 0,
signature, &sig_len, mbedtls_ctr_drbg_random, &ctr_drbg)) != 0) {
printf("RSA signing failed: -0x%04X\n", -ret);
goto exit;
}
// 8. 验签
if ((ret = mbedtls_pk_verify(&pub_key, md_info->type, hash, 0, signature, sig_len)) != 0) {
printf("RSA verify sign failed: -0x%04X\n", -ret);
goto exit;
}
printf("sign and verify ok! \n");
exit:
mbedtls_pk_free(&priv_key);
mbedtls_pk_free(&pub_key);
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
return ret;
}
/**
* 使用公钥私钥验证加密数据
*/
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_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;
}
// 2. 初始化一个基于Counter with CBC-MAC (CTR) mode and Deterministic Random Byte Generator (DRBG)的伪随机数生成器(PRNG)实例
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);
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(priv_key), mbedtls_ctr_drbg_random, &ctr_drbg, MBEDTLS_RSA_PUBLIC, &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 private_pk_context;
mbedtls_pk_context public_pk_context;
mbedtls_rsa_context *rsa_private_key;
mbedtls_rsa_context rsa_public_key;
mbedtls_pk_init(&private_pk_context);
mbedtls_pk_init(&public_pk_context);
mbedtls_rsa_init(&rsa_public_key, MBEDTLS_RSA_PKCS_V15, 0);
// 1. 加载PEM格式的私钥文件
ret = mbedtls_pk_parse_keyfile(&private_pk_context, "./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(&private_pk_context) != MBEDTLS_PK_RSA) {
printf("Private key is not an RSA key.\n");
return -1;
}
// 3. 获取RSA上下文
rsa_private_key = mbedtls_pk_rsa(private_pk_context);
// if (mbedtls_rsa_check_pubkey(&rsa_private_key) != 0 ||
// mbedtls_rsa_check_privkey(&rsa_private_key) != 0 ) {
// printf("Filed check key rsa ctx.\n");
// return -1;
// }
// 4. 解析 N、D、E 参数
const mbedtls_mpi *N = &rsa_private_key->N;
const mbedtls_mpi *E = &rsa_private_key->E;
const mbedtls_mpi *D = &rsa_private_key->D;
printf("rsa private: \n");
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);
// // 5. 从私钥中提取公钥
if (mbedtls_rsa_copy(&rsa_public_key, rsa_private_key) != 0) {
// 处理错误,例如打印错误信息
printf("Failed to copy public key from private key: -0x%04x\n", -ret);
return -1;
}
// N = &rsa_public_key.N;
// E = &rsa_public_key.E;
// D = &rsa_public_key.D;
// printf("rsa public: \n");
// 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);
__free_resource:
// 清理资源
mbedtls_pk_free(&private_pk_context);
mbedtls_pk_free(&public_pk_context);
mbedtls_rsa_free(rsa_private_key);
mbedtls_rsa_free(&rsa_public_key);
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_PRIKEY_PEM_LEN 4096
#define MAX_PUBKEY_PEM_LEN (MAX_PRIKEY_PEM_LEN/2)
/**
* 将 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 = RK_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 = RK_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;
}
void test_pem_str_to_rsa(void)
{
static const char *private_key_pem =
"-----BEGIN RSA PRIVATE KEY-----\n"
"MIIEogIBAAKCAQEAiRn2/fk3w2xQVWaEBUHfCQb84eG6ir8VcOg7hJReW1bEAWEd\n"
"280DoyfwIthYkHKmmhVGN1TvhpuAn72a8c98pOuhO8QpSmDFYC6TSbCrznPhR4IS\n"
"VQKR0w6EwJIkIWSg4CFxjY2yeWAjdDxRWSjuxGEGncaLBqlFx7zBEteWhai3XxH+\n"
"xu9AnHzcbxpmlRd88L6hxBEbLTBt+sSDxVlFVjZaE+8Iex8e5BNCambRe9kusXtK\n"
"bmXdFQ16MIdItpbfFhbqkLwAuAGoMf0Hyn2vyRuaigLQ3OlXJ9Sqp+F5VAVC0eQ+\n"
"NgMrwA4vRNxJ3L0PZj1S1fnzHHyAlKp3Mdv9mQIDAQABAoIBAHb6Al7KbHr5vwkt\n"
"iropPM1PtBqt0j1fr9KopiXav7uSI0xzI/8//b0UBo+moczQwgWLGsEfwzFUNx3o\n"
"49Ke1bMlDGmaRJ7YNdDO+mCDocTqyQBOP2xoa3X17nxTFmmoMvft7eYCpnQwWvQe\n"
"+BVgsTvYW26GAtYIBZddFUwtrOFVkEm0ubiAWwTj2gvmb69MhlkZB8+5tN44+c0F\n"
"txhwRZePo4nLcB4G/b8OoZiAntL14YPTDffHiuFf7JYY9FJcrNdlfcehh2a4kKct\n"
"BgeFDVObwi/W2X8NUCRZniZNv3gh6cKBSb5pRCvP+dBuR2t6t2UHOgjdZuKlWCj7\n"
"VT9pdVECgYEAwu3+OSpIUqWDVqQyrC0O9HH6l+7ulsRn7GJRusFaIoVgIYP+APhp\n"
"PFr85o1AG6z76C9Zri9LOds3bFkrp88N2H/sumDaikZs1RbXS+g4rDAjN1T/WK2p\n"
"Cps2DAEvWRV2eBmGRm07onumNpL4YiYMCCFuIhfdwCwJp9SwutVUCX0CgYEAtA30\n"
"ei3IAKA30f//9dVKmYeWJysY9n+dQzZsE+ubbtoMwfqs6YaO/rxT9KLM6cNyLMRX\n"
"m70VO63rgdofrvORL4L+EOzdVuE2cfFtPEefwEc8bfCcvqlEgb8ltY7zvw3DLrfe\n"
"AUrUaDyT6hdKJuBZnCvo+3ltkb+/nKuPY1dbH00CgYB8GsP5p0bmf4QwHFg6sHFO\n"
"BmcyZie3C5LSuAIq8cEuK1Z54CxOd9mgWJmdO57uP+Md/0+Mi4XMbxpJPDiEHVpG\n"
"VaPlQZbB5HaT8HfgVxgF4Jv7NX1g+yednhX57KM1h2mmqzGHEzKdjzXSlx3Wdzy/\n"
"zHDu+dzv5dm75bkjKoDXjQKBgCk5bLkwlDM4e69UGqmRbSQbvBA5uNxvOXVzF2m0\n"
"LwFBYVxkZYSOL105h0tinuICwrhnN9vLffoNBvfTFh/7Wklzh3IemUrUA6Aw856y\n"
"k2v1o2tUhL7OiIXgWuTn1vzuTLr8lBLdrCY1gHQ/YtXl1f6AuzYghiqxqVBYo1rO\n"
"XGmdAoGAVwTfacddPFL01jCrAJrqnEfsmoYLROdVejAszYPfVqgLw90/4qOd3eh1\n"
"rz7dHs9gW52AHaqIJhdFYhG/Dltve2M0y7HpI8l19KbZnkoXFccec4cCpqZSARBL\n"
"QXAqPPhqIGev8gCYGl4pO08Lcfsj3aI5WtmmpdYmhtt5Tzuj8h8=\n"
"-----END RSA PRIVATE KEY-----\n";
INT ret;
mbedtls_pk_context pk_ctx;
mbedtls_pk_init(&pk_ctx);
// 解析 PEM 格式的私钥
if ((ret = mbedtls_pk_parse_key(&pk_ctx, (const unsigned char *) private_key_pem,
strlen(private_key_pem) + 1, NULL, 0)) != 0) {
printf("mbedtls_pk_parse_key returned -0x%04X\n", -ret);
return -1;
}
printf("Private key parsed successfully.\n");
mbedtls_rsa_context *rsa;
// 3. 获取RSA上下文
rsa = mbedtls_pk_rsa(pk_ctx);
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);
static const char *public_key_pem =
"-----BEGIN PUBLIC KEY-----\n"
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiRn2/fk3w2xQVWaEBUHf\n"
"CQb84eG6ir8VcOg7hJReW1bEAWEd280DoyfwIthYkHKmmhVGN1TvhpuAn72a8c98\n"
"pOuhO8QpSmDFYC6TSbCrznPhR4ISVQKR0w6EwJIkIWSg4CFxjY2yeWAjdDxRWSju\n"
"xGEGncaLBqlFx7zBEteWhai3XxH+xu9AnHzcbxpmlRd88L6hxBEbLTBt+sSDxVlF\n"
"VjZaE+8Iex8e5BNCambRe9kusXtKbmXdFQ16MIdItpbfFhbqkLwAuAGoMf0Hyn2v\n"
"yRuaigLQ3OlXJ9Sqp+F5VAVC0eQ+NgMrwA4vRNxJ3L0PZj1S1fnzHHyAlKp3Mdv9\n"
"mQIDAQAB\n"
"-----END PUBLIC KEY-----\n";
mbedtls_pk_free(&pk_ctx);
mbedtls_pk_init(&pk_ctx);
if((ret = mbedtls_pk_parse_public_key(&pk_ctx, public_key_pem, strlen(public_key_pem) + 1)) != 0) {
printf("mbedtls_pk_parse_key returned -0x%04X\n", -ret);
return -1;
}
rsa = mbedtls_pk_rsa(pk_ctx);
N = &rsa->N;
E = &rsa->E;
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);
}
INT main(int argc, char const *argv[])
{
// mbedtls_rsa_self_test(1); // 局部测试函数
// test_rsa_gen_N_E_D(); // rsa 公私钥生成, pem 写文件, 读取转换测试
// test_N_E_D_encry_hw(fd); // 硬件加密测试
// test_rsa_encry(); // 加密测试
// test_rsa_sign_verify_pkcs(); // 签名验签测试, pkfs 接口
// test_pem_to_rsa(); // 验证接口
test_pem_str_to_rsa(); // 验证字符串解析
// test_rsa_sign_verify_mbedtls(); // 签名验签测试, mbedtls 接口
// test_rsa_encry_with_rkrng(); // 测试加减密, 使用 rkrng 设备
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");
}
本文来自博客园踩坑狭,作者:韩若明瞳,转载请注明原文链接:https://www.cnblogs.com/han-guang-xue/p/18122413