openssl 密鑰生成和解析

最近豹储,在寫java讀取key的時候遇到了一個version的問題。不解淘这,就各種找資料剥扣,這里總結(jié)一下.

ANS.1編碼規(guī)則

openssl的數(shù)據(jù)編碼規(guī)則是基于ans.1:

ASN.1(=Abstract Syntax Notation One),是一種結(jié)構(gòu)化的描述語言铝穷,包括兩部分,數(shù)據(jù)描述語言和數(shù)據(jù)編碼規(guī)則钠怯。

  • 數(shù)據(jù)描述語言標(biāo)準(zhǔn):語言標(biāo)準(zhǔn)允許用戶自定義的基本數(shù)據(jù)類型,并可以通過簡單的數(shù)據(jù)類型組成更復(fù)雜的數(shù)據(jù)類型曙聂。
  • 數(shù)據(jù)編碼規(guī)則:這些編碼方法規(guī)定了將數(shù)字對象轉(zhuǎn)換成應(yīng)用程序能夠處理晦炊、保存、傳輸?shù)亩M(jìn)制形式的一組規(guī)則宁脊。

標(biāo)準(zhǔn)ASN.1編碼規(guī)則有規(guī)范編碼規(guī)則(CER断国,Canonical Encoding Rules)、唯一編碼規(guī)則(DER榆苞,Distinguished Encoding Rules)稳衬、壓縮編碼規(guī)則(PER,Packed Encoding Rules)和XML編碼規(guī)則(XER坐漏,XML Encoding Rules)薄疚。

所謂的規(guī)則碧信,就是數(shù)據(jù)流編解碼的方式。編碼:將數(shù)據(jù)結(jié)構(gòu)(可能是不同的输涕,異構(gòu)的)變成數(shù)據(jù)流音婶;解碼:其他應(yīng)用讀取解析,獲得相應(yīng)數(shù)據(jù)莱坎。

Step 1:數(shù)據(jù)格式定義

對于普通數(shù)據(jù)類型衣式,我們將數(shù)據(jù)直接轉(zhuǎn)化成數(shù)據(jù)流進(jìn)行傳輸即可;對于復(fù)雜數(shù)據(jù)格式檐什,需要引入一個數(shù)字對象的概念碴卧,通過將復(fù)雜數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)化成數(shù)據(jù)對象。

ASN.1的第一部分---數(shù)據(jù)描述語言標(biāo)準(zhǔn)乃正,這個標(biāo)準(zhǔn)定義了一些基本的數(shù)據(jù)類型住册,如果我們使用到復(fù)雜的數(shù)據(jù)結(jié)構(gòu),asn.1還允許通過簡單數(shù)據(jù)類型組成復(fù)雜的數(shù)據(jù)類型(x.509)瓮具。

Step 2:數(shù)據(jù)流轉(zhuǎn)化

數(shù)據(jù)傳輸需要將數(shù)據(jù)(結(jié)構(gòu)或者對象)轉(zhuǎn)化成數(shù)據(jù)流(二進(jìn)制流)進(jìn)行傳輸荧飞。

ASN.1的第二部分--編碼規(guī)則,編碼方法規(guī)定了將數(shù)字對象轉(zhuǎn)換成應(yīng)用程序能夠處理名党、保存叹阔、傳輸?shù)亩M(jìn)制形式的一組規(guī)則。

所以传睹,ASN.1標(biāo)準(zhǔn)就是規(guī)定了把數(shù)據(jù)轉(zhuǎn)化成數(shù)據(jù)對象耳幢,又規(guī)定數(shù)據(jù)對象編碼為二進(jìn)制流的方法。

openssl使用的是asn.1的der編碼規(guī)則欧啤,保證每個asn.1對象使用der編碼獲得的二進(jìn)制編碼是唯一的睛藻。

openssl使用pem作為基本的文件編碼格式,pem和der的關(guān)系如下圖所示邢隧,其中幾種加密環(huán)節(jié)是可選的:


image.png

從本質(zhì)上來說店印,openssl是pem編碼就是在der編碼的技術(shù)上進(jìn)行Base64編碼,然后添加一些頭尾信息組成府框,可以通過openssl指令對der和pem進(jìn)行格式轉(zhuǎn)換吱窝。

證書編碼格式

常見的證書編碼格式有三種X.509證書,PKCS#12證書和PKCS#7證書迫靖。

X.509證書

最常用的證書格式,它僅包含了公鑰信息而沒有私鑰信息兴使,一個openssl簽發(fā)經(jīng)過PEM編碼的X.509證書格式如下:

-----BEGIN CERTIFICATE-----
XXX
-----END CERTIFICATE-----

中間部分就是經(jīng)過PEM編碼的X509證書系宜。除了上述形式的頭尾格式,還可能出現(xiàn)以下兩種不同的標(biāo)識符发魄。

-----BEGIN X.509 CERTIFICATE----
XXX
-----END X.509 CERTIFICATE-----

或者

-----BEGIN TRUSTED  CERTIFICATE-----
XXX
-----END TRUSTED  CERTIFICATE-----

X.509證書文件的后綴名經(jīng)常是der盹牧,cer或者crt俩垃。openssl的指令x509提供了對X.509證書進(jìn)行格式轉(zhuǎn)換的方法。

PKCS#12證書

PKCS12證書可以包含一個或者多個證書汰寓,并且還可以包含證書對應(yīng)的私鑰口柳。openssl的pkcs12指令可以將X.509格式的證書和私鑰封裝成PKCS#12格式的證書,也可以將PKCS#12證書轉(zhuǎn)換成X.509證書有滑。

PKCS#12證書的后綴名通常是p12或者pdx跃闹。

PKCS#7證書:

PKCS#7可以封裝一個或者多個X.509證書或者PKCS#6證書,并且可以包含CRL信息毛好。PKCS#7證書中也不包含私鑰信息望艺。openssl提供了crl2pkcs7和pkcs7兩個指令來生成和處理PKCS#7文件,可以使用他們在X.509證書和PKCS#7證書之間進(jìn)行轉(zhuǎn)換和處理

PKCS#7證書的后綴名是p7b

密鑰編碼

openssl有多種形式的密鑰肌访,openssl提供PEM和DER兩種編碼方式對這些密鑰進(jìn)行編碼找默,并提供相關(guān)指令可以使用戶在這兩種格式之間進(jìn)行轉(zhuǎn)換。

openssl密鑰大致可以分為兩種吼驶,一種是可以公開的惩激,例如公鑰,一種是不能公開的蟹演,比對私鑰风钻。反映在編碼上,有的密鑰需要加密轨帜,有的密鑰就不需要加密魄咕。一個經(jīng)過加密的PEM編碼密鑰文件會在PEM文件中增加一些頭信息,表明密鑰的加密狀態(tài)蚌父,加密算法及初始化向量等信息

openssl指令提供了對密鑰加密的功能哮兰,并提供了多種可選的對稱加密算法,比如DES和DES3苟弛。當(dāng)對密鑰進(jìn)行加密的時候通常需要用戶輸入口令喝滞,這里的口令并非直接用來作為加密的密鑰,而是根據(jù)這個口令使用一系列HASH操作來生成一個用戶加密密鑰數(shù)據(jù)的密鑰膏秫。當(dāng)讀取這類密鑰的時候右遭,同樣需要輸入同樣的口令。

這里再詳細(xì)的說下DER和PEM缤削。

DER

DER就是密鑰的二進(jìn)制表述格式窘哈。

Distinguished Encoding Rules (DER) is a binary serialization of ASN.1 format. It is often used for cryptographic data such as certificates, but has other uses.

PEM

PEM格式就是對DER編碼轉(zhuǎn)碼為base64字符格式。通過base64解碼可以還原DER格式亭敢。

A PEM file is plain text. It contain one or more objects, such as certificates or keys, which may not all be the same type. Each object is delimited by lines similar to “—–BEGIN …—–” and “—–END …—–”. Data that is not between such lines is ignored, and is sometimes used for comments, or for a human-readable dump of the encoded data.

Following the “BEGIN” and “END” keywords is a name (such as “CERTIFICATE”) that can be used as an identifier for the type of object.

The data between the delimiter lines starts with an optional email-like header section, followed by base64-encoded payload data. After decoding, the payload data is in DER format.

PEM 是明文格式滚婉,可以包含證書或者是密鑰;其內(nèi)容通常是以類似 “—–BEGIN …—–” 開頭 “—–END …—–” 為結(jié)尾的這樣的格式進(jìn)行描述的帅刀。
因為DER是純二進(jìn)制格式让腹,對人不友好远剩,所以一般都用PEM進(jìn)行存儲。這里主要介紹PEM格式的公私鑰骇窍。

公鑰PEM

PKCS #1

PKCS #1 標(biāo)準(zhǔn)是專門為 RSA 密鑰進(jìn)行定義的瓜晤,其對應(yīng)的 PEM 文件格式如下,

-----BEGIN RSA PUBLIC KEY-----
BASE64 ENCODED DATA
-----END RSA PUBLIC KEY-----

上面的內(nèi)容 BASE64 ENCODED DATA 指的就是 ANS.1 的 DER 的 Base64 編碼腹纳。其ASN.1的格式為:

RSAPublicKey ::= SEQUENCE {
    modulus           INTEGER,  -- n
    publicExponent    INTEGER   -- e
}

各個filed的含義:

  • modulus 是RSA的合數(shù)模n痢掠。
  • publicExponent 是RSA公開冪e。
PKCS #8

PKCS#8 標(biāo)準(zhǔn)定義了一個密鑰格式的通用方案只估,它不僅僅為 RSA 所使用志群,同樣也可以被其它密鑰所使用。其對應(yīng)的PEM文件格式如下:

-----BEGIN PUBLIC KEY-----
BASE64 ENCODED DATA
-----END PUBLIC KEY-----

注意蛔钙,這里就沒有 RSA 字樣了锌云,因為 PKCS#8 是一個通用型的秘鑰格式方案;其中的 BASE64 ENCODED DATA 所標(biāo)注的內(nèi)容為 PEM 格式中對 DER 原始二進(jìn)制進(jìn)行的 BASE64 編碼:

PublicKeyInfo ::= SEQUENCE {
  algorithm       AlgorithmIdentifier,
  PublicKey       BIT STRING
}
AlgorithmIdentifier ::= SEQUENCE {
  algorithm       OBJECT IDENTIFIER,
  parameters      ANY DEFINED BY algorithm OPTIONAL
}

PKCS#8 雖然名字叫做 Private-Key Information Syntax Specification吁脱,但是實際上桑涎,可以看到,它同樣可以用作 Public Key 的格式定義兼贡;而 PKCS#8 是站在 PKCS#7 CMS 的基礎(chǔ)之上進(jìn)行編碼格式定義的攻冷。

私鑰PEM

PKCS #1

PKCS#1 是專門為 RSA 所涉及的,其對應(yīng)的 PEM 格式如下:

-----BEGIN RSA PRIVATE KEY-----
BASE64 ENCODED DATA
-----END RSA PRIVATE KEY-----

原始的 DER 格式結(jié)構(gòu)遍希,既是 ASN.1 的數(shù)據(jù)結(jié)構(gòu):

RSAPrivateKey ::= SEQUENCE {
  version           Version,
  modulus           INTEGER,  -- n
  publicExponent    INTEGER,  -- e
  privateExponent   INTEGER,  -- d
  prime1            INTEGER,  -- p
  prime2            INTEGER,  -- q
  exponent1         INTEGER,  -- d mod (p-1)
  exponent2         INTEGER,  -- d mod (q-1)
  coefficient       INTEGER,  -- (inverse of q) mod p
  otherPrimeInfos   OtherPrimeInfos OPTIONAL
}

其中各個字段的含義為:

  • version 是版本號等曼,兩個素數(shù)為0,如果使用了多素數(shù)凿蒜,則版本號應(yīng)該是1禁谦。
    Version ::= INTEGER { two-prime(0), multi(1) }
    (CONSTRAINED BY {-- version must be multi if otherPrimeInfos present --})
  • modulus 是RSA合數(shù)模n。
  • publicExponent 是RSA的公開冪e废封。
  • privateExponent 是RSA的私有冪d州泊。
  • prime1 是n的素數(shù)因子p。
  • prime2 是n的素數(shù)因子q漂洋。
  • exponent1 等于d mod (p ? 1)遥皂。
  • exponent2 等于d mod (q ? 1)。
  • coefficient 是CRT系數(shù) q–1 mod p刽漂。
  • otherPrimeInfos 按順序包含了其它素數(shù)r3, …, ru的信息演训。如果version是0 ,它應(yīng)該被忽略贝咙;而如果version是1,它應(yīng)該至少包含OtherPrimeInfo的一個實例眯娱。
PKCS #8
未加密

PEM格式:

-----BEGIN PRIVATE KEY-----
BASE64 ENCODED DATA
-----END PRIVATE KEY-----

對應(yīng)的DER:

PrivateKeyInfo ::= SEQUENCE {
  version         Version,
  algorithm       AlgorithmIdentifier,
  PrivateKey      BIT STRING
}
AlgorithmIdentifier ::= SEQUENCE {
  algorithm       OBJECT IDENTIFIER,
  parameters      ANY DEFINED BY algorithm OPTIONAL
}
加密

針對私鑰的內(nèi)容進(jìn)行加密。
PEM格式:

-----BEGIN ENCRYPTED PRIVATE KEY-----
BASE64 ENCODED DATA
-----END ENCRYPTED PRIVATE KEY-----

DER格式:

EncryptedPrivateKeyInfo ::= SEQUENCE {
  encryptionAlgorithm  EncryptionAlgorithmIdentifier,
  encryptedData        EncryptedData
}
EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
EncryptedData ::= OCTET STRING

openssl操作

生成私鑰

openssl有多種方法生成私鑰:

  • genrsa生成RSA密鑰穿剖。
  • req在生成req證書請求時同時產(chǎn)生密鑰。
  • genpkey除了可以生成RSA密鑰外,還可以生成DSA救巷、DH密鑰谜酒。

使用genpkey命令生成RSA私鑰文件,選擇DES-EDE3-CBC算法進(jìn)行加密唆貌,口令是1234:
openssl genpkey -algorithm RSA -out privatekey.pem -pass pass:1234 -des-ede3-cbc

生成私鑰文件,其密鑰長度為1024诱担。

這里還可以直接生成Openssl ASN格式的key:

-----BEGIN RSA PRIVATE KEY-----  
Proc-Type: 4,ENCRYPTED  
DEK-Info:DES-EDE3-CBC,4D5D1AF13367D726  
BASE64私鑰內(nèi)容  
-----END RSA PRIVATE KEY----- 

還有很多格式施籍,比如微軟的PVK等诈茧。Openssl ASN格式在加密私鑰數(shù)據(jù)時只能用MD5算法生成key,而且只迭代計算了1次曾沈。所以從1.0.0開始Openssl把PKCS#8格式作為默認(rèn)格式障涯,可以為私鑰文件提供更好的安全性和擴(kuò)展性匙姜。

genrsa生成ASN格式的key畅厢;
rsa生成或者轉(zhuǎn)化為PVK格式:openssl rsa -in privatekey.pem -out privatekey.pvk -outform PVK

解析私鑰

使用asn1parse命令讀取私鑰SAN.1結(jié)構(gòu)郭计,其中-i表示使用縮進(jìn)格式霸琴。

openssl asn1parse -i -in privatekey.pem 

其ASN.1輸出格式為:

    0:d=0  hl=3 l= 135 cons: SEQUENCE          
    3:d=1  hl=2 l=   1 prim:  INTEGER           :01
    6:d=1  hl=2 l=  19 cons:  SEQUENCE          
    8:d=2  hl=2 l=   7 prim:   OBJECT            :id-ecPublicKey
   17:d=2  hl=2 l=   8 prim:   OBJECT            :prime256v1
   27:d=1  hl=2 l= 109 prim:  OCTET STRING      [HEX DUMP]:306B02010104204B42FE59E4C16B8BDD516E23AE880BBBC2662D28DD6B461C0364D639F691FBCCA144034200040EE3526C590136A6DD9467F0C17487296BF8A70D9E14E783F955C21D5E0212B04A9D45C18B073F9CBEFAE94CD79D69EC8D4529DD9392CC209FE7A70D90B9AFE9

每一行的意義大概為:

  • 0 表示節(jié)點在整個文件中的偏移長度
  • d=0 表示節(jié)點深度
  • hl=3 表示節(jié)點頭字節(jié)長度
  • l=135 表示節(jié)點數(shù)據(jù)字節(jié)長度
  • cons 表示該節(jié)點為結(jié)構(gòu)節(jié)點,表示包含子節(jié)點或者子結(jié)構(gòu)數(shù)據(jù)
  • prim 表示該節(jié)點為原始節(jié)點昭伸,包含數(shù)據(jù)
  • SEQUENCE梧乘、OCTET STRING等都是ASN.1中定義的數(shù)據(jù)類型,具體可以參考ASN.1格式說明

最后一個節(jié)點OCTET STRING [HEX DUMP]选调,就是加密后的私鑰數(shù)據(jù)夹供。

參考鏈接

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市仁堪,隨后出現(xiàn)的幾起案子哮洽,更是在濱河造成了極大的恐慌,老刑警劉巖弦聂,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸟辅,死亡現(xiàn)場離奇詭異,居然都是意外死亡莺葫,警方通過查閱死者的電腦和手機(jī)匪凉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捺檬,“玉大人再层,你說我怎么就攤上這事”の常” “怎么了聂受?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長烤镐。 經(jīng)常有香客問我蛋济,道長,這世上最難降的妖魔是什么职车? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任瘫俊,我火速辦了婚禮,結(jié)果婚禮上悴灵,老公的妹妹穿的比我還像新娘扛芽。我一直安慰自己,他們只是感情好积瞒,可當(dāng)我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布川尖。 她就那樣靜靜地躺著,像睡著了一般茫孔。 火紅的嫁衣襯著肌膚如雪叮喳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天缰贝,我揣著相機(jī)與錄音馍悟,去河邊找鬼。 笑死剩晴,一個胖子當(dāng)著我的面吹牛锣咒,可吹牛的內(nèi)容都是我干的侵状。 我是一名探鬼主播,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了冀墨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤航瞭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡蹋凝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了辛臊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仙粱。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖彻舰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情候味,我是刑警寧澤刃唤,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站白群,受9級特大地震影響尚胞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜帜慢,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一笼裳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧粱玲,春花似錦躬柬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至卵沉,卻和暖如春颠锉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背史汗。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工琼掠, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人停撞。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓瓷蛙,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子速挑,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容