X509證書中RSA公鑰的提取與載入 pem key

 

轉載地址:http://hi.baidu.com/ehxanwmqkpbcnsq/item/233b48d35b3f841820e25043

 

 

由於項目需要,我計劃利用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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章