原地址:https://blog.csdn.net/anddy926/article/details/8940377

由于项目需要,我计划利用openssl开发一个基本的CA,实现证书的发放等功能。在项目模型中公私钥对是用户自己产生的,并且以16进制数的形似提交给CA。我们知道,通常利用openssl颁发证书时,公私钥对往往也是由openssl产生的,比如利用以下三个函数RSA_generate_key
EVP_PKEY_assign_RSA
X509_set_pubkey
便可以轻松搞定从密钥产生到载入证书的过程,而提取证书公钥只需
X509_get_pubkey
如何将16进制形式的rsa公钥载证书的却没有相关介绍,经过几天的研究终于搞定了,贴出来与大家分享,我们可以利用下面的函数
RSA* d2i_RSAPublicKey(NULL,(const unsigned **) pp,int len)
其中*pp指向存储公钥的内存单元,len指公钥的长度,请注意这里的公钥是指经过ASN.1编码的公钥,关于此编码方法,要想全面阐述是相当复杂的,但如果仅限于编rsa公钥,则会简单很多,以下是1024位rsa公钥的ASN.1编码的十六进制描述,共占据140bytes:
30 81 89 02 81 81 00 e3 8d 99 06 9f bd 9a c0 e5 
6a 5d 03 b3 cf 09 ca 8e c1 4a 6c f9 90 c2 46 e0 
89 44 69 cd a5 62 91 42 8a 5f e5 8f d3 fb 93 3f 
bc d7 6e 5e f2 80 41 a6 79 78 8e 4d 1d 3d 65 ad 
d4 36 9c c5 83 55 9d f1 bb 20 4c b7 6c 95 37 b0 
37 06 e3 40 fb 8f 74 c3 59 91 a2 bf a2 e1 db 99 
54 29 5f 9b a5 57 f5 40 7a 54 82 9c 84 d4 35 86 
14 38 69 14 60 f3 c6 c7 11 75 f2 43 2c 34 ed 89 
4a ae e1 9d 57 3e a1 02 03 01 00 01ASN.1采用Tag,Lenth,Value,编码方式,在此将整个编为一个sequence,可以理解为结构体,以30作为开始标志,第二位81代表后面有1字节代表长度,即89代表长度(若为82则代表后面有两字节代表长度,依次类推),转化成十进制为137,正好与后面的字节数吻合,从第四位02开始便是此sequence的内涵,相当于结构体的元素,一般来说sequence往往需要嵌套,相当于结构体嵌结构体,但对公钥的sequence来说,此处仅有一层。第四位02代表一下的内容为bit流,同样紧随其后的81代表有一字节代表长度,第六位的81代表长度为129,即从00开始直到最后一行a1此为129字节,去掉前面的00,余下128位便是rsa公钥的N值,最后5个字节同样是bit流,以02开始,03表示长度为3,最后的01 00 01 便是rsa公钥的E值。关于为什么要在N值前补00,这可能是ASN.1的规定,若bit流的前四bit十六进制值小于8就要在在最前补零,看下面的例子30 81 88 02 81 80 32 8d 99 06 9f bd 9a c0 e5 6a 
5d 03 b3 cf 09 ca 8e c1 4a 6c f9 90 c2 46 e0 89 
44 69 cd a5 62 91 42 8a 5f e5 8f d3 fb 93 3f bc 
d7 6e 5e f2 80 41 a6 79 78 8e 4d 1d 3d 65 ad d4 
36 9c c5 83 55 9d f1 bb 20 4c b7 6c 95 37 b0 37 
06 e3 40 fb 8f 74 c3 59 91 a2 bf a2 e1 db 99 54 
29 5f 9b a5 57 f5 40 7a 54 82 9c 84 d4 35 86 14 
38 69 14 60 f3 c6 c7 11 75 f2 43 2c 34 ed 89 4a 
ae e1 9d 57 3e a1 02 03 01 00 01N的前四bit为0x3小于8,因此无需补零。关于什么情况下要在tag值之后用8X标明有几位代表length,我的理解是,如果length的前四bit大于8或超过一字节,则必需用8X标明,否则不用。言规正传,了解了rsa公钥的编码规则,我们便可以方便的将用其他工具产生的rsa公钥编为openssl可接受的码型,从而完成公钥的导入,对于公钥的提取,同样有函数int i2d_RSAPublicKey(RSA *,(const char **))返回值为公钥的长度,当然是经ASN.1编码后的。完成了bit流与RSA的转化,剩下的工作便有很轻松了,在此在介绍几种简便方法,可以直接在bit与EVP_PKEY之间转化:导出:len=i2d_RSAPublicKey(pkey->pkey.rsa,(const char**)pp);导入要多几步:pkey->save_type=6;
pkey->type=EVP_PKEY_type(6);
pkey->pkey.rsa=d2i_RSAPublicKey(NULL,(const char**)pp,len);其中pkey的定义为EVP_PKEY *pkey;导入过程中前两行的作用是设定采用的密码算法为rsa,若采用bit-〉rsa-〉pkey模式,这个工作由EVP_PKEY_assign_RSA替我们做了。

我接触openssl4个月了,以上我的经验总结,欢迎大家批评指正。

PEM文件格式详细解析 收藏 
PEM文件格式存档

Author:Roson sun

Time:2006-4-11

1. 描述:

Openssl使用PEM(RFC 1421-1424)文档格式,如果使用其他语言包,则需要将此格式进行解码并将各个私公钥加入。

2. 说明:

a)         首先使用BASE64解码,如果是非ANSI TXT格式,需要做转换。

b)        一个RSA私钥包含一下信息(1024位):

>openssl rsa -in key.pem -noout -text

modulus:

00:d5:00:b2:18:c3:04:d1:ac:80:c6:22:a0:cc:5c:

f1:c0:4a:83:95:e5:c9:88:ae:31:64:ab:e1:15:42:

de:1a:da:bc:f5:d2:05:05:74:9d:d3:86:94:9b:9d:

74:bb:e5:72:a4:b8:40:27:61:88:d4:ac:20:b0:2b:

1c:1e:d7:9b:43:c5:06:b6:3a:b4:42:f0:5a:22:38:

23:74:99:4a:50:f1:f1:54:11:5a:44:0b:40:cf:83:

8a:73:6c:34:15:98:0a:7d:cf:0e:e5:00:8d:07:40:

f7:7d:fb:3f:64:35:1b:5d:a3:40:a9:51:fa:92:7d:

34:ef:03:fe:e0:59:56:31:25

数量:128

publicExponent:

01:00:01

数量:3

privateExponent:

11:e2:a8:11:ba:36:6a:60:c0:c3:62:5e:fc:2a:05:

c6:ae:bb:13:d8:22:af:0e:69:69:59:a1:61:c6:a6:

9d:bc:a6:47:41:e6:58:09:ed:c2:b8:37:3c:45:e1:

6a:71:9e:c9:c4:0a:e7:03:a2:98:b1:07:61:a3:8d:

0d:ed:ee:c4:7f:ca:fe:7d:c1:2e:2f:ca:3d:16:81:

4f:bf:ad:6a:03:ca:d7:80:dc:57:03:fe:cf:1f:37:

05:8d:58:79:14:01:1f:66:42:e4:f1:b6:9d:f1:01:

37:12:f4:d8:15:c0:cc:9b:fc:ea:55:cb:2f:ba:46:

fd:17:11:7e:43:b5:d1:15

数量:128

prime1:

00:ed:a0:e8:25:cc:1c:aa:f5:44:e2:78:9e:54:2c:

1d:60:cb:8f:32:b3:68:6d:b3:1d:cd:a9:8c:2a:ca:

02:bc:7b:a7:8b:06:1d:fa:af:4f:8c:26:81:54:12:

ec:7d:92:20:77:85:ef:6e:06:a6:8b:9c:eb:ab:6a:

e6:a1:83:6d:a3

数量:64(去掉开头的0)

prime2:

00:e5:78:66:5a:84:22:51:78:2d:14:fc:5f:f8:4e:

45:5f:e3:b2:5e:5b:50:a4:f5:55:e0:f3:0e:98:2c:

52:61:c2:50:df:f4:b7:bc:6e:69:3e:99:ff:1c:50:

a8:89:05:7a:2b:25:91:56:a5:a6:8f:8a:ec:80:82:

fa:eb:09:c2:97

数量:64(去掉开头的0)

exponent1:

00:89:e6:26:d2:48:71:1a:84:db:44:d1:da:8f:de:

49:ee:32:33:17:a9:25:a1:03:a0:f8:08:bc:5e:d8:

7c:5e:05:24:65:79:57:4c:73:10:26:b4:f1:b8:68:

82:f5:1c:27:db:34:ce:8d:7b:2e:8b:36:b5:4c:f4:

ec:82:2e:53:21

数量:64(去掉开头的0)

exponent2:

6a:16:a6:e3:74:31:55:8f:04:f0:ad:d9:44:b8:13:

14:c8:f5:5e:f0:42:b1:71:07:5a:2f:a4:f0:af:95:

0a:c3:46:96:b3:d1:fa:58:e5:69:5e:d2:f5:e9:48:

71:c8:c9:79:87:2d:d1:6c:56:3c:08:d3:5c:7a:b1:

bc:d6:4f:53

数量:64

coefficient:

62:dd:3f:f4:c7:30:c7:77:5e:8c:ae:c8:11:c1:23:

b0:6d:7d:07:54:8f:e7:12:1d:e1:00:ad:70:55:12:

43:f6:6f:a9:d7:94:9d:33:15:66:16:2d:d1:76:13:

33:0d:ae:6f:e3:3f:46:4b:4a:78:14:02:2e:72:66:

59:0c:2d:6a

数量:64

c)        与C#中RSAParameter结构体对应表:

说明
PEM
RSAParameter

Modulus
modulus

Exponent
Exponent

prime1
P

exponent1
Q

prime2
DP

exponent2
DQ

coefficient
InverseQ

privateExponent
D

d)        PEM偏移(1024位,以0为开始字符,十进制)

说明
PEM私钥
PEM公钥
长度

Modulus
11
29
128

PublicExponent
141
159
3

PrivateExponent
147
×
128

Prime1
278
×
64

Prime2
345
×
64

Exponent1
412
×
64

Exponent2
478
×
64

Coefficient
545
×
64

[转载]X509证书中RSA公钥的提取与载入 pem key的更多相关文章

  1. X509证书中RSA公钥的提取与载入

    原文链接: http://blog.chinaunix.net/uid-16515626-id-2741894.html   由于项目需要,我计划利用openssl开发一个基本的CA,实现证书的发放等 ...

  2. openssl 获取证书中的公钥

    PEM 格式 1.  FILE *fp = fopen("xx.pem", "r"); 2.  X509 *cert = PEM_read_X509(fp, N ...

  3. openssl rsa加密,解密以及X509证书的使用

    Openssl的相关使用 生成证书 生成证书见:使用 openssl 生成证书 代码实现 Cert.h #ifndef _CERT_H #define _CERT_H ///header files ...

  4. OpenSSL 使用拾遗(二)---- X509 证书的 SKID/AKID 字段

    SKID(证书使用者密钥标识符,subject key identifier 的简称)和 AKID(证书颁发机构密钥标识符,authority key identifier 的简称)是 X509 证书 ...

  5. MQTT研究之EMQ:【JAVA代码构建X509证书】

    这篇帖子,不会过多解释X509证书的基础理论知识,也不会介绍太多SSL/TLS的基本信息,重点介绍如何用java实现SSL协议需要的X509规范的证书. 之前的博文,介绍过用openssl创建证书,并 ...

  6. 使用windows crypt API解析X509证书

    一.版本号 结构体CERT_INFO中的字段dwVersion即为证书版本,可以直接通过下面的代码获得: DWORD dwCertVer = m_pCertContext->pCertInfo- ...

  7. openssl解析国密X509证书

    openssl解析国密X509证书,把公钥拿出来重写一下就行了        x = strToX509(pbCert, pulCertLen);dwRet = getCertPubKey(x, &a ...

  8. openssl 学习之从证书中提取RSA公钥N 和 E

    原文链接: http://blog.csdn.net/kkxgx/article/details/19850509 通常数字证书包含很多信息,其中N和E值即我们称为的公钥.如何从PEM 或者DER格式 ...

  9. 你竟然在公钥中下毒!——如何在RSA公钥中添加后门

    原文:http://www.hackdig.com/?01/hack-17893.htm 分享到: 当我知道它是如何运行时,我惊得下巴都掉了.这是一个非常简单的手法,但这篇文章会颠覆你之前对RSA的看 ...

随机推荐

  1. 1-ES简单介绍

    一.ES简单介绍 ES:Elastic Search,一个分布式.高扩展.高实时的搜索与数据分析引警.它可以准实时地快速存储.搜索.分析海量的数据. 1.ES实现原理 a.用户数据提交到ES数据库中 ...

  2. React -- 3/100 】组件通讯

    通讯 | props | prop-types 组件通讯 Props: 组件无论是使用函数声明还是通过 class 声明,都决不能修改自身的 props /* class */ .parent-box ...

  3. eclipse多个项目提交到同一个仓库(码云)

    参考博客:Eclipse提交多个项目到同一个仓库 https://blog.csdn.net/qq_30764991/article/details/80379365 步骤一:码云建立个远程仓库 步骤 ...

  4. "Host 'onlyyou-bridal.jp' is blocked because of many connection errors; unblock with 'mysqladminlush-hosts'"

    错误链接数太多 ,清理mysqladminlush-hosts 这个文件 直接 service mysqld restart  解决了~~~ ccess denied for user 'root'@ ...

  5. Azure IoT 技术研究系列2

    上篇博文中,我们主要介绍了Azure IoT Hub的基本概念.架构.特性: Azure IoT 技术研究系列1-入门篇 本文中,我们继续深入研究,做一个起步示例程序:模拟设备注册到Azure IoT ...

  6. vscode 编写Markdown文件

    vscode使用Markdown文档编写   首先安装vscode工具,具体的使用可以参考之前的博文:<Visual Studio Code教程:基础使用和自定义设置> VScode已经默 ...

  7. RPC协议解析

    RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议.简言之,RPC使得程序能够像访问本地 ...

  8. sql server,mysql 和navicat for mysql的区别

    一.定义 sql server 应该指的是sqlserver数据库,包含数据库管理系统等. navicat for sql server只是一个sqlserver的第三方的开发工具,管理工具. 二.开 ...

  9. Python---协程---重写多线程

    一. # 用协程的方式,修改播放电影和音乐的练习题 # 用协程的方式完成播放 movie_list = ["斗破.mp4", "复仇者联盟.avi", &quo ...

  10. php----等比缩放图片

    <?php /** * Created by PhpStorm. * User: admin * Date: 2019/11/19 * Time: 8:54 */ $filename = 'lo ...