RSA为非对称加密算法,关于其介绍可以参考:https://blog.csdn.net/fengbingchun/article/details/43638013。

OpenSSL最新版为 1.1.1g,在Windows上和Linux上编译源码时均可以生成可执行文件openssl。通过此执行文件即可产生rsa公钥-私钥对,如产生长度为3072的密钥对,具体命令及执行结果如下图所示:3072是指modulus即模数长度为3072bit,即384字节。

LD_LIBRARY_PATH=../lib ./openssl genrsa -out rsa_private.pem 3072

rsa_private.pem中既包含了私钥信息也包含了公钥信息,从rsa_private.pem私钥中提取公钥命令如下:

LD_LIBRARY_PATH=../lib ./openssl rsa -in rsa_private.pem -pubout -out rsa_public.pem

PEM格式与DER格式:PEM格式就是在DER格式基础上进行BASE64编码,然后添加一些头尾信息或标签组成的,用于说明当前的文件格式,是一种约定俗称,如头信息为” -----BEGIN RSA PRIVATE KEY-----”,尾信息为” -----END RSA PRIVATE KEY-----”,中间的数据部分即是对DER进行base64编码后的结果。

使用openssl asn1parse命令解析pem文件的结果如下所示:

在解析rsa_public.pem文件时没有显示出数据,其中BIT STRING的内容就是公钥PKCS#1格式的公钥数据,若显示数据,需要添加个偏移选项参数-strparse,在这里偏移值是19,添加后的执行结果如下:输出的数据与私钥文件中的n,e相同

PKCS即Public Key Cryptography Standards,公钥加密标准,一共有15个标准,编号从1到15。OpenSSL中RSA使用的是PKCS#1。PKCS#1定义了RSA的数理基础、公/私钥格式,以及加/解密、签/验章的流程。

通过以下命令可以把PEM格式转换成DER格式,执行结果如下:与上面结果相同

私钥(rsa_private.pem)包括:modulus(n), public exponent(e), private exponent(d), prime 1(p), prime 2(q), exponent 1(exp1), exponent 2(exp2) and coefficient(coeff)。公钥(rsa_public.pem)包括:modulus(n) and public exponent(e)。其中n、e、d会被直接用于加密、解密,其它几个用来校验。

下面用code实现从rsa_private.pem和rsa_public.pem中获取n, e, d等数据:

int test_openssl_parse_rsa_pem_private_key()
{
#ifdef _MSC_VERconst char* name = "E:/GitCode/OpenSSL_Test/testdata/rsa_private.pem";
#elseconst char* name = "testdata/rsa_private.pem";
#endifFILE *fp = fopen(name, "rb");if (!fp) {fprintf(stderr, "fail to open file: %s\n", name);return -1;}RSA* rsa = PEM_read_RSAPrivateKey(fp, nullptr, nullptr, nullptr);if (!rsa) {fprintf(stderr, "fail to PEM_read_bio_RSAPrivateKey\n");return -1;}fclose(fp);ASN1_INTEGER* n = BN_to_ASN1_INTEGER(RSA_get0_n(rsa), nullptr); // modulusASN1_INTEGER* e = BN_to_ASN1_INTEGER(RSA_get0_e(rsa), nullptr); // public exponentASN1_INTEGER* d = BN_to_ASN1_INTEGER(RSA_get0_d(rsa), nullptr); // private exponentASN1_INTEGER* p = BN_to_ASN1_INTEGER(RSA_get0_p(rsa), nullptr); // prime 1ASN1_INTEGER* q = BN_to_ASN1_INTEGER(RSA_get0_q(rsa), nullptr); // prime 2ASN1_INTEGER* dmp1 = BN_to_ASN1_INTEGER(RSA_get0_dmp1(rsa), nullptr); // exponent 1ASN1_INTEGER* dmq1 = BN_to_ASN1_INTEGER(RSA_get0_dmq1(rsa), nullptr); // exponent 2ASN1_INTEGER* iqmp = BN_to_ASN1_INTEGER(RSA_get0_iqmp(rsa), nullptr); // coefficientif (!n || !e || !d || !p || !q || !dmp1 || !dmq1 || !iqmp) {fprintf(stderr, "fail to BN_to_ASN1_INTEGER\n");return -1;}print(n, "n");print(e, "e");print(d, "d");print(p, "p");print(q, "q");print(dmp1, "exp1");print(dmq1, "exp2");print(iqmp, "coeff");ASN1_INTEGER_free(n);ASN1_INTEGER_free(e);ASN1_INTEGER_free(d);ASN1_INTEGER_free(p);ASN1_INTEGER_free(q);ASN1_INTEGER_free(dmp1);ASN1_INTEGER_free(dmq1);ASN1_INTEGER_free(iqmp);RSA_free(rsa);return 0;
}

以上code是用于从rsa_private.pem私钥中提取n,e,d等数据的实现,主要使用的是PEM_read_RSAPrivateKey函数,执行结果如下,与通过命令上获取到的数据相同:

int test_openssl_parse_rsa_pem_public_key()
{
#ifdef _MSC_VERconst char* name = "E:/GitCode/OpenSSL_Test/testdata/rsa_public.pem";
#elseconst char* name = "testdata/rsa_public.pem";
#endifFILE *fp = fopen(name, "rb");if (!fp) {fprintf(stderr, "fail to open file: %s\n", name);return -1;}// use PEM_read_RSA_PUBKEY instead of PEM_read_RSAPublicKey// https://stackoverflow.com/questions/7818117/why-i-cant-read-openssl-generated-rsa-pub-key-with-pem-read-rsapublickey// https://stackoverflow.com/questions/18039401/how-can-i-transform-between-the-two-styles-of-public-key-format-one-begin-rsa/29707204#29707204RSA* rsa = PEM_read_RSA_PUBKEY(fp, nullptr, nullptr, nullptr);if (!rsa) {fprintf(stderr, "fail to PEM_read_bio_RSAPublicKey\n");return -1;}fclose(fp);ASN1_INTEGER* n = BN_to_ASN1_INTEGER(RSA_get0_n(rsa), nullptr); // modulusASN1_INTEGER* e = BN_to_ASN1_INTEGER(RSA_get0_e(rsa), nullptr); // public exponentif (!n || !e) {fprintf(stderr, "fail to BN_to_ASN1_INTEGER\n");return -1;}print(n, "n");print(e, "e");ASN1_INTEGER_free(n);ASN1_INTEGER_free(e);RSA_free(rsa);return 0;
}

以上code是从rsa_public.pem公钥中提取n,e数据的实现,注意这里用到的函数是PEM_read_RSA_PUBKEY而不是PEM_read_RSAPublicKey,执行结果如下,与从私钥中提取的n,e数据相同:

以上代码段的完整code见:GitHub/OpenSSL_Test

GitHub:https://github.com/fengbingchun/OpenSSL_Test

从openssl rsa pem文件中提取公私钥数据实现相关推荐

  1. ffmpeg-从mp4、flv、ts文件中提取264视频流数据

    ffmpeg-从mp4.flv.ts文件中提取264视频流数据 main.c #include <stdio.h> #include <libavutil/log.h> #in ...

  2. ffmpeg-从flv文件中提取AAC音频数据保存为文件

    AAC ADTS格式协议: 从flv文件中提取AAC音频数据保存为文件. 如果需要详细了解AAC ADTS格式,可以查询文档. 原文件: 提取aac文件: main.c #include <st ...

  3. 实战:从文件夹中庞大的excel(.xlsx)文件中提取并整合数据

    从文件夹中庞大的excel(.xlsx)文件中提取并整合数据 Input 需要从文件夹树中提取有格式的单个数据格并汇总. 例如: 2017-2020x市蚊虫数据/2018/7月/abcds方法统计.x ...

  4. klg日志文件中提取RGBD图像数据

    main函数 本程序用于从klg日志文件中提取RGB图像和Depth图像信息,klg文件在ElasticFusion中被用于保存数据集. 涉及的相关开源代码如下: LogView mp3guy/Log ...

  5. C语言 从txt文件中提取特定的数据

    C语言:从txt中逐行读取文本,提取其中的特殊数据 在Matlab中几行正则化的操作,C中尝试实现. 问题描述 在大量的txt中提取其中的特定数据 例如: Labeled Markers (4):Ma ...

  6. 在csv文件中提取特定的数据做图-以天气为例子

    前言:这是在<python入门>中的一个例子,写成文章,作为学习的复盘. 现在有这么一份天气数据,需要将画出最高温和最低温的曲线图. 前期的基础知识: CSV文件 CSV是最通用的一种文件 ...

  7. python调用simulink_使用Python从dbc文件中提取simulink建模数据定义

    使用dbc文件建模完成CAN通讯是一种比较高效的开发模式,不过在建模的过程中dbc文件中描述的数据需要自己去定义.使用文本编辑工具打开dbc文件可以看到,实际上dbc文件是一个可以进行语义解析的文本. ...

  8. openssl 从cer文件中提取公钥

    openssl x509 -in XX.cer -pubkey  -noout > XX.pem

  9. 从flv文件中提取音频并存储为mp3格式

    在优酷上下载了一些教学视频,为了把它们放到mp3里面,需要从这些flv文件中提取出音频数据并存储为mp3格式. 操作系统是centos 5.3. 在网上搜索了一下,找到以下方法: 方法一:使用menc ...

  10. 从keystore(jks)文件中提取私钥

    JKS文件是使用keytool生成的keystore文件,存放私钥和证书.但是我们用keytool的时候,私钥并没有单独生成出来.这个不利于我们后期的一些扩展工作.所以,我们需要把私钥从keytool ...

最新文章

  1. 令人拍案叫绝的Wasserstein GAN
  2. js实现html模板继承,理解JavaScript中的原型和继承
  3. Educational Codeforces Round 103 (Rated for Div. 2)A~E解题报告
  4. 用jQuery实现页面遮罩弹出框
  5. SQL中的join的详细用法!inner join,full outer join,left join,right jion
  6. keyboard dialog 仿微博表情键盘输入框
  7. CSDN自定义模块简单设置之——添加图片、文字、链接等
  8. .join()用法 | python学习
  9. 负压式爬壁机器人_负压吸附式爬壁机器人的体重设计
  10. 图解“华为云潮汕火锅”的“牛里乾坤”
  11. LeetCode/LintCode 题解丨一周爆刷字符串:神奇字符串
  12. MSTAR软件框架!
  13. 7 士兵排队---PTA(排序+中位数)(C++)
  14. 烤仔观察 | 哈耶克最后的预言
  15. 安卓 View 开发 绘制尺子
  16. UTC GMT EST CST 区别
  17. 华清远见上海中心22071班 9.7作业
  18. 《设计模式》读书笔记——创建型模式
  19. Mysql学习记录(6)
  20. 网络安全——通用渗透测试框架

热门文章

  1. 乐理基础-曲谱、简谱、音名、唱名、调、调号
  2. 西门子PLC S7 200 SMART 没有触摸屏的仿真
  3. Linux 进程之如何查看进程详情?
  4. java 获取拼音_Java获取汉字对应的拼音(全拼或首字母)
  5. Hdu-5053 the Sum of Cube(水题)
  6. 卡尔曼滤波算法-Kalman filter
  7. Java毕业设计-资产管理系统
  8. JAVA音乐网站(JAVA毕业设计)
  9. 【线性代数01】矩阵的转置和逆
  10. 解决用SSIS组件导入CSV文件时,把CSV文件名一起插入到数据库表中的问题