You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenSSL:如何从RSA结构体将生成的密钥导出到C字符数组?

将RSA密钥对导出到C字符数组的实现方法

嗨,刚好碰到过类似的需求!你已经用RSA_generate_key_ex生成了RSA密钥对,确实PEM_write_RSAPublicKey这类函数只能写文件,但OpenSSL的内存BIO接口可以完美解决这个问题——我们可以把密钥先写入内存缓冲区,再把缓冲区里的数据复制到C字符数组里。

下面是整合到你现有代码里的完整实现,包含公钥和私钥的导出:

#include <openssl/rsa.h>
#include <openssl/bn.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
#include <stdlib.h>
#include <stdio.h>

int main() {
    int ret = 0; 
    RSA *r = NULL; 
    BIGNUM *bne = NULL; 
    char *pub_key = NULL;
    char *pri_key = NULL;
    BIO *pub_bio = NULL;
    BIO *pri_bio = NULL;

    bne = BN_new(); 
    ret = BN_set_word(bne, RSA_F4); 
    if(ret != 1) { 
        BN_free(bne); 
        return 0; 
    } 

    r = RSA_new(); 
    ret = RSA_generate_key_ex(r, 2048, bne, NULL); 
    if(ret != 1){ 
        RSA_free(r); 
        BN_free(bne); 
        return 0; 
    } 

    // -------------------------- 导出公钥到C字符数组 --------------------------
    pub_bio = BIO_new(BIO_s_mem());
    if (!pub_bio) {
        goto cleanup;
    }
    // 将公钥写入内存BIO
    if (!PEM_write_bio_RSAPublicKey(pub_bio, r)) {
        goto cleanup;
    }
    // 获取内存中数据的长度
    size_t pub_len = BIO_pending(pub_bio);
    // 分配字符数组(+1是为了存储字符串终止符)
    pub_key = malloc(pub_len + 1);
    if (!pub_key) {
        goto cleanup;
    }
    // 从BIO读取数据到数组
    BIO_read(pub_bio, pub_key, pub_len);
    pub_key[pub_len] = '\0'; // 添加字符串终止符,方便作为C字符串使用

    // -------------------------- 导出私钥到C字符数组 --------------------------
    pri_bio = BIO_new(BIO_s_mem());
    if (!pri_bio) {
        goto cleanup;
    }
    // 将私钥写入内存BIO(NULL表示不加密私钥,若需要加密可以传入密码相关参数)
    if (!PEM_write_bio_RSAPrivateKey(pri_bio, r, NULL, NULL, 0, NULL, NULL)) {
        goto cleanup;
    }
    size_t pri_len = BIO_pending(pri_bio);
    pri_key = malloc(pri_len + 1);
    if (!pri_key) {
        goto cleanup;
    }
    BIO_read(pri_bio, pri_key, pri_len);
    pri_key[pri_len] = '\0';

    // 这里可以使用pub_key和pri_key,比如打印出来验证
    printf("Public Key:\n%s\n", pub_key);
    printf("Private Key:\n%s\n", pri_key);

cleanup:
    // 释放所有资源,避免内存泄漏
    if (pub_key) free(pub_key);
    if (pri_key) free(pri_key);
    if (pub_bio) BIO_free(pub_bio);
    if (pri_bio) BIO_free(pri_bio);
    if (r) RSA_free(r);
    if (bne) BN_free(bne);
    return ret == 1 ? 1 : 0;
}

关键知识点说明:

  • 内存BIO:BIO_s_mem()创建一个基于内存的BIO对象,相当于内存缓冲区,用来替代文件指针作为写入目标。
  • PEM内存写入函数:PEM_write_bio_RSAPublicKey和PEM_write_bio_RSAPrivateKey是对应文件版本的内存版API,专门用来将密钥写入内存BIO。
  • 数据读取:BIO_pending()可以获取BIO中已写入的数据长度,用这个长度来分配字符数组的大小,之后用BIO_read()把数据从BIO复制到数组里。
  • 资源释放:所有分配的内存和OpenSSL对象都要记得释放,示例里用goto cleanup统一处理释放逻辑,是C语言里常用的资源管理方式。

内容的提问来源于stack exchange,提问作者81Vm3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 22:37:38