祝各位道友念头通达
GitHub Gitee 语雀 打赏

公钥私钥和模数指数相互转换

  • 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");
}
posted @ 2024-04-08 19:52  韩若明瞳  阅读(234)  评论(0编辑  收藏  举报