使用OpenSSL工具制作X.509證書的方法及其註意事項總結
怎樣使用OpenSSL工具生成根證書與應用證書
本文由CSDN-蚍蜉撼青松 【主頁:http://blog.csdn.net/howeverpf】原創。轉載請註明出處!
?
零、寫在前面
? ? ? ?近期出於工作須要,倒騰了一下怎樣生成X.509證書。在此過程中遇到一些問題。也查過網上非常多資料,磕磕碰碰,總算依照既定要求達到了目標。由於感覺網上的資料太散。查找起來不非常方便,所以在這裏做一個總結。
? ? ? ?基本的參考信息來源是下面三個:
- 《OpenSSL編程》(趙春平 著)【一本難得的中文資料,未出版】
- 《OpenSSL官方文檔---OpenSSL命令》(英文),差點兒能夠找到全部問題的答案和原因,可是由於非常多時候不知道問題出在哪裏,所以還是須要另外查資料
- 《互動百科---SSL》,說明了證書中各DN字段的含義
? ? ? ??一些前輩的博文,也對我高速定位問題提供了非常大的幫助,在此表示感謝!並列舉例如以下:
- 博客園 -?rusty,《Openssl使用生成CA總結》 ,提到了須要提前建好一些文件夾和文件
- 百度空間 -?mars208,《使用openssl創建CA》,提到了簽發策略的問題
- ChinaUnix?-?ehyyngp,《使用openssl簽發證書》,提到了中級證書的簽發問題
?
一、步驟簡記
? ? ? ?以生成一個二級證書鏈為例,將會用到下面命令:
// 生成頂級CA的公鑰證書和私鑰文件。有效期10年(RSA 1024bits,默認) openssl req -new -x509 -days 3650 -keyout CARoot.key -out CARoot.crt // 為頂級CA的私鑰文件去除保護口令 openssl rsa -in CARoot.key -out CARoot.key // 生成頂級CA的公鑰證書和私鑰文件。有效期15年(RSA 2048bits。指定) openssl req -newkey rsa:2048 -x509 -days 5480 -keyout CARoot.key -out CARoot.crt // 為頂級CA的私鑰文件去除保護口令 openssl rsa -in CARoot.key -out CARoot.key // 為應用證書/中級證書生成私鑰文件 openssl genrsa -out app.key 2048 // 依據私鑰文件。為應用證書/中級證書生成 csr 文件(證書請求文件) openssl req -new -key app.key -out app.csr // 使用CA的公私鑰文件給 csr 文件簽名,生成應用證書,有效期5年 openssl ca -in app.csr -out app.crt -cert CARoot.crt -keyfile CARoot.key -days 1826 -policy policy_anything // 使用CA的公私鑰文件給 csr 文件簽名。生成中級證書,有效期5年 openssl ca -extensions v3_ca -in app.csr -out app.crt -cert CARoot.crt -keyfile CARoot.key -days 1826 -policy policy_anything
? ? ? ?依據生成目標不同。以上命令能夠分為三組。當中,前面兩組都用於生成自簽名的頂級CA(差別僅僅在於密鑰長度不同),實際應用中僅僅需依據需求選擇一組就可以。
? ? ? ?最後一組用於生成非自簽名的證書。包含中級證書與應用證書。所謂中級證書,是具有繼續頒發下級證書權限的子CA。而本文中所說的應用證書,特指不能用來繼續頒發下級證書,僅僅能用來證明個體身份的證書。頂級CA在簽發二者的時候。僅僅是多少一個?-extensions v3_ca 選項的差別,這個選項賦予被簽發的證書繼續簽發下級證書的權力。
【詳參2.5[3]小節相關介紹】
二、各步具體解釋
2.1 生成自簽名根證書(即頂級CA)
典型演示樣例:openssl req?-new?-x509?-days?5480?-keyout?CA.key?-out?CA.crt
[1] 命令選項和參數解讀
? ? ? ?演示樣例中,各選項(及參數)的意義例如以下:
req //使用openssl的req子命令
-new //生成新的證書請求
-x509 //生成自簽名證書
-days 5480 //自簽名證書的有效期5480天(15年)【僅當使用了 -x509?選項後有效】
-keyout CA.key //私鑰文件名稱指定為CA.key【此選項的一般作用是新生成文件命名。但若同一時候使用了-key選項,則此選項用於原私鑰文件的更名】
-out CA.crt //指定輸出所生成自簽名證書的信息到文件。且文件名稱為CA.crt【建議不要省略】
? ? ? ?當中。-days。-keyout 兩個選項能夠省略,省略的話使用默認值。有效期默覺得 30 天【由程序內部在變量初始化的時候指定,與配置文件無關】。私鑰文件名稱的默認值由配置文件?openssl.cnf?中相關條目指定。沒改過的話為?privkey.pem。
? ? ? ?選項 -out 若是省略的話,openssl不會以文件形式輸出生成的 證書/證書請求。而是會默認將文件的信息直接打印到屏幕上,這在大多數情況下,是不符合我們要求的。所以建議這個選項最好不要省略!
? ? ? ?req子命令能夠通過?-key 選項為證書請求指定使用一個已存在的私鑰文件。但在演示樣例中的情況下。盡管使用了-new 和 -x509兩個選項。但沒有使用?-key 選項,這時。req子命令會自己主動為自簽名證書生成一個RSA私鑰。密鑰長度的默認值由配置文件?openssl.cnf?中的相關條目指定,沒改過的話為 1024 bits。
[2] 關於私鑰文件加密口令的指定
? ? ? ?執行中會提示輸入加密口令。例如以下:
writing new private key to ‘CA.key‘
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
? ? ? ?此口令用於加密私鑰文件 CA.key 中的私鑰信息,假設不想在執行過程中還要輸入加密口令,則能夠使用選項?-passout?在命令中直接指定。
選項?-passout 的使用形式為:
-passout?arg
當中。arg是選項?-passout 的參數,其格式有多種。詳參《OpenSSL官方文檔》中關於"PASS_PHRASE_ARGUMENTS"的介紹。
? ? ? ?本小節典型演示樣例中的命令,能夠用選項?-passout?改造例如以下:
openssl req -new?-x509?-days?5480?-keyout?CA.key -out CA.crt?-passout?pass:1314
? ? ? ?由於Linux系統中能夠使用history命令查看歷史指令記錄。所以出於安全方面的考量,一般如非必要。不建議在命令中直接指定口令。
這與mysql登錄的時候不在 -p 選項裏直接指定登錄口令的原因是一致的。
[3] 關於證書請求文件裏的DN字段
? ? ? ?執行中會提示輸入一些 Distinguished Name fields,即證書的識別名信息字段,簡稱為DN字段,例如以下:
You are about to be asked to enter information that will be incorporated into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.‘, the field will be left blank.
-----
Country Name (2 letter code) [GB]:US
State or Province Name (full name) [Berkshire]:California
Locality Name (eg, city) [Newbury]:
Organization Name (eg, company) [My Company Ltd]:GeoAuth Inc.
Organizational Unit Name (eg, section) []:.
Common Name (eg, your name or your server‘s hostname) []:Authentication Global Root
Email Address []:.
? ? ? ?這些DN字段大部分有默認值。默認值由配置文件 openssl.cnf中相關條目指定。如要在某一個DN字段使用默認值。則無需輸入不論什麽信息,直接點擊"Enter"鍵;假設確實某個DN字段的值要置為空。則輸入一個?‘.‘ 後,點擊"Enter"鍵。
? ? ? ?這些DN字段主要是拿來識別證書持有者身份的,下表是關於它們的縮寫、說明和一些填寫說明。【此部分參考了互動百科的SSL條目】
?
DN字段名 | 縮寫 | 說明 | 填寫要求 |
Country Name | C | 證書持有者所在國家 | 要求填寫國家代碼,用2個字母表示 |
State or Province Name | ST | 證書持有者所在州或省份 | 填寫全稱。可省略不填 |
Locality Name | L | 證書持有者所在城市 | 可省略不填 |
Organization Name | O | 證書持有者所屬組織或公司 | 不妨填一下 |
Organizational Unit Name | OU | 證書持有者所屬部門 | 可省略不填 |
Common Name | CN | 證書持有者的通用名 | 必填。 對於非應用證書,它應該在一定程度上具有惟一性; 對於應用證書,一般填寫服務器域名或通配符樣式的域名。 |
Email Address | ? | 證書持有者的通信郵箱 | 可省略不填 |
?
表2-1?DN字段的說明
?
註:表中所謂,證書不是應用證書時,其持有者的通用名要有“唯一性”。是指其通用名不要與一般主機上常見的信任證書列表或撤銷證書列表中的證書產生反復。
? ? ? ?假設不想在執行過程中逐個輸入這些DN字段的值,則能夠使用?-subj?選項在命令中直接指定。
選項?-subj?的使用形式為:
-subj?arg
當中。arg是選項?-subj?的參數。其格式相似於:/type0=value0/type1=value1/type2=... 形式。
每個?/type=value?形式的單元,都相應了一個完整的DN字段。
當中,
- / 是每個DN字段的開始標誌;
- type0、type1等等,就是表2-1中提到的DN字段名的縮寫。
- =是DN字段的名和值之間的間隔符;
- value0、value1等等。就是原本你要在執行過程中逐個輸入的DN字段的值。
? ? ? ?對於您要將值置為空的DN字段,您能夠略去不寫。本小節典型演示樣例中的命令,能夠用?-subj?選項改造例如以下【略去了 L 與 OU 兩個DN字段】:
openssl req -new?-x509?-days?5480?-subj?/C=US/ST=California/O=GeoAuth\ Inc./CN=Authentication\ Global\ Root -keyout CA.key -out CA.crt
? ? ? ?須要特別註意的是,假設您設定的DN字段的值假設存在一些特殊字符【比方 ?(空格)、((半角左括號)、)(半角右括號)……】,必須經過\(反斜桿)轉義。
上例中已經給出了空格轉義的情況。
[4] 怎樣指定自簽名證書的密鑰長度和類型
? ? ? ?如前所述,演示樣例僅僅能生成密鑰長度為1024bits的RSA公私鑰對。
假設要生成密鑰長度不為1024bits的RSA公私鑰對,或是其它類型的【比方DSA、EC】公私鑰對。則必須使用選項 -newkey 來取代?-new 。
選項 -newkey 的使用方法比較復雜,如需具體了解,請參看《OpenSSL官方文檔》的相關頁面。本小節典型演示樣例中的命令等效於下面命令:
openssl req -newkey?rsa:1024 -x509?-days?5480?-keyout?CA.key?-out?CA.crt
要生成一個密鑰長度為2048bits的RSA公私鑰對,命令為:
openssl req -newkey?rsa:2048 -x509?-days?5480?-keyout?CA2048.key?-out?CA2048.crt
2.2?為頂級CA的私鑰文件去除加密保護
? ? ? ?上節提到,頂級CA的私鑰文件是經過加密保護的,以後每當需讀取?CA.key 文件裏的私鑰信息時。都需輸入解密口令。這樣的做法適合有安全需求的場合。但假設覺得不方便,也能夠去除這個口令。
典型演示樣例:openssl rsa?-in?CA.key?-out?CA.key
[1] 命令選項和參數解讀
? ? ? ?演示樣例中,各選項/參數的意義例如以下:
rsa //使用openssl的rsa子命令
-in CA.key //經加密保護的私鑰文件
-out CA.key //解除加密保護後的私鑰文件【能夠改名】
[2] 關於私鑰文件解密口令的指定
? ? ? ?執行中會提示輸入解密口令,例如以下:。
Enter pass phrase for CA.key:
writing RSA key
? ? ? ?假設不想在執行過程中還要輸入解密口令,則能夠使用選項?-passin?在命令中直接指定。選項?-passin 的使用形式為:
-passin?arg
當中。arg是選項?-passin?的參數,其格式同選項?-passout 的參數,詳參《OpenSSL官方文檔》中關於"PASS_PHRASE_ARGUMENTS"的介紹。
? ? ? ?本小節典型演示樣例中的命令。能夠用選項?-passin?改造例如以下:
openssl rsa -in?CA.key -out?CA.key?-passin pass:1314
? ? ? ?基於同選項?-passout 一樣的考量,一般不建議直接在命令中指定解密口令。
[3] rsa子命令的實際功能
? ? ? ?rsa子命令的功能。更完整來說,應該是RSA密鑰的管理。除了此處用到的去除加密保護。還能夠用來:更換加解密口令。更換加解密算法【DES、三重DES、IDEA(官方文檔上提到過,可是有些版本號好像不支持,比方說我安裝的)、AES(官方文檔上沒提到。我安裝的版本號支持)】,更換密鑰文件的編碼方式等等。
?
2.3?為應用證書/中級證書生成私鑰文件
典型演示樣例:openssl genrsa?-out?app.key?2048
?
[1] 命令選項和參數解讀
? ? ? ?演示樣例中,各選項/參數的意義例如以下:
?
genrsa //使用openssl的genrsa子命令
-out app.key //指定輸出生成的私鑰信息到文件,且文件名稱為app.key【建議別省略】
2048 //指定所生成私鑰的比特長度【務必放在最後一個】
?
? ? ? ?當中。選項 -out 若是省略的話,openssl不會以文件形式輸出生成的 私鑰信息,而是會默認將私鑰的信息直接打印到屏幕上。這不符合我們的要求。
所以建議這個選項不要省略!
? ? ? ?genrsa子命令還能夠有其它一些選項及參數,但不論還有多少選項。都必須把指定私鑰長度的參數放在最後一個。
【假設指定私鑰長度的參數不是最後一個,則其後的參數好像會被舍棄。】
[2] 私鑰文件的加密保護
? ? ? ? 本小節典型演示樣例所給出的命令。生成的是未經不論什麽加密保護的私鑰文件。這樣的方式用起來比較方便。但非常不安全。假設要為私鑰文件附加加密保護。則有兩種方式:
- A.在生成私鑰文件的同一時候就指定輸出前要用某種加密算法加密保護;
- B.生成明文的私鑰文件後用 rsa 子命令附加某種加密算法的加密保護。
? ? ? ?我計算機上安裝的openssl版本號,在兩種方式下都支持這些加密算法選項:-des,-des3。-aes128。-aes192。-aes256。以加密選用192位的AES算法為例,命令例如以下:
// 在生成私鑰文件的同一時候就指定輸出前要用192位的AES算法加密保護
openssl genrsa -aes192 -out app.key 1024
// 生成明文的私鑰文件後用 rsa 子命令附加192位的AES算法加密保護
openssl rsa -aes192 -in app.key -out app.key
? ? ? ?上例中的兩個命令。都會要求在執行中輸入加密口令。相同的。盡管不建議,可是openssl依舊支持在命令中使用選項?-passout 指定加密口令,選項?-passout 的使用方法參考2.1[2]小節。唯一須要額外註意的是,對於genrsa子命令。選項?-passout 應放在 指定密鑰長度的參數 前面。
2.4?為應用證書/中級證書生成 csr 文件【證書請求文件】
典型演示樣例:openssl req?-key?app.key?-out?app.csr
[1] 命令選項和參數解讀
? ? ? ?演示樣例中。各選項/參數的意義例如以下:
req //使用openssl的req子命令
-new //生成新的證書請求
-key app.key //指定是為app.key文件裏的私鑰生成證書請求
-out app.csr //指定輸出所生成證書請求的信息到文件。且文件名稱為app.csr
? ? ? ?這和2.1節使用的是openssl的同一個子命令。所以參數的意義非常多具有共通性。
命令執行中也會要求輸入一些DN字段的值。參看本文2.1 [3] 小節中的相關介紹。
相同的。能夠使用-subj選項在命令中直接指定這些DN字段的值。
2.5 為 csr 文件簽名。生成應用證書/中級證書
典型演示樣例:openssl ca?-in?app.csr?-out?app.crt?-cert?CA.crt?-keyfile?CA.key?-days?1826?-policy?policy_anything
[1] 命令選項和參數解讀
? ? ? ?演示樣例中,各選項/參數的意義例如以下:
ca //使用openssl的ca子命令
-in app.csr //指定待簽發證書的 CSR文件為 app.csr
-out app.crt //指定輸出所簽發證書的信息到文件。且文件名稱為app.crt【建議不要省略】
-cert CA.crt //指定為應用/中級證書簽名的CA的公鑰證書為CA.crt【用到CA證書的持有者信息】
-keyfile CA.key //指定為應用/中級證書簽名的CA的私鑰文件為CA.key【用CA私鑰實際執行簽名】
-days 1826 //指定所簽發證書的有效期為1826天(5年)
-policy policy_anything //指定簽發策略為 policy_anything?【即,同意所簽發證書的持有者信息和頒發者信息之間不遵守不論什麽匹配策略】
? ? ? ?當中。選項 -out 若是省略的話,openssl不會以文件形式輸出生成的 應用證書/中級證書信息。而是會默認將證書的信息直接打印到屏幕上。這一般不符合我們的要求。
所以建議這個選項不要省略!
[2] 關於簽發策略
? ? ? ? 在本節的典型演示樣例中,我們使用了選項-policy來指定簽發策略為 policy_anything。假設沒有使用此選項,則簽發策略使用由配置文件?openssl.cnf?中相關條目指定的默認策略。假設您沒動過該配置文件的話,則默認策略為?policy_match。此策略要求CA的公鑰證書和應用證書請求文件裏的Country Name、State or Province Name、Organization Name這三個字段必須?match?【也就是一樣】。假設您在應用證書請求文件裏指定了和CA的公鑰證書不一樣的Country Name,且沒有使用選項-policy,則會得到相似於下方的提示:
The countryName field needed to be the same in the
CA certificate (US) and the request (CN)
? ? ? ? 查看配置文件?openssl.cnf?中相關條目,我們能夠看到下面內容,
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_match
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# For the ‘anything‘ policy
# At this point in time, you must list all acceptable ‘object‘
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
? ? ? ?看到這,原因就非常顯然了。所以若是您要在應用證書請求文件裏指定和CA的公鑰證書不一樣的C/ST/O。且要簽名成功。則有下面三種方式:
- 加上-policy選項,指定本次使用的簽發策略為 policy_anything;
- 將配置文件?openssl.cnf?中的默認策略由 policy_match改成 policy_anything;
- 將策略?policy_match 中的相關條目由 match改成 optional?。
? ? ? ?為什麽openssl會使用這樣的默認策略呢?事實上非常easy,openssl認定。僅當您建立組織內部的信任關系時,您才須要自己做CA。
既然是組織內部的信任關系。當然CA和應用證書就該有一樣的所在國家、所在省份,以及所屬組織。
[3] 關於簽發中級證書(二級/三級CA,子CA)
? ? ? ? 由本節典型演示樣例命令生成的證書僅僅能作為應用證書,由於它不具有繼續簽署下級證書的權限。下圖展示了中級證書與應用證書的差別。
圖2-1?中級證書與應用證書的差別
? ? ? ? 由上圖能夠看出,二者主要是在證書的擴展字段Subject Type的取值有所不同。中級證書該字段取值為"CA",表明此證書依舊能夠作為CA。繼續簽發下級證書;一般應用證書該字段的取值為"End Entity"。表明這已經是證書鏈的最後一個結點,自然也就不能繼續簽發下級證書。
? ? ? ? 查看配置文件?openssl.cnf?中相關條目。能夠看到例如以下內容:
[ ca ]
default_ca = CA_default # The default ca section
……………………
[ CA_default ]
……………………
x509_extensions = usr_cert # The extentions to add to the cert
……………………
[ usr_cert ]
# These extensions are added when ‘ca‘ signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
……………………
[ v3_ca ]
……………………
# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true
……………………
? ? ? ? 由此能夠看出,為什麽默認生成的都是純應用證書。若要生成中級證書(通常是出於信任關系建立的便利)。則有下面方式:
?
- 上級CA在簽署此證書時,加上 -extensions 選項。且選項參數設為?v3_ca (如步驟簡記中所看到的);
- 將?CA_default 條目中?x509_extensions?的值由?usr_cert改為?v3_ca;
- 將?usr_cert 條目中?basicConstraints的值由?CA:FALSE 改為?CA:true;
?
[4] 關於批處理模式
? ? ? ? 執行本節典型演示樣例命令生成證書時。會遇到相似於下面的提示:
?
Certificate is to be certified until Mar 27 03:44:08 2015 GMT (365 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
? ? ? ??也就是說,這個命令是有交互的,你必須在執行過程中手工完畢兩次確認輸入。
但我們在自己生成證書鏈的時候,證書請求文件和CA證書都是由我們自己生成的,一般並不須要確認。另外,我們一旦須要用程序自己主動化/批量化處理。也會顯得麻煩。
?
? ? ? ??說究竟,一句話,假設你不想有交互。那麽能夠使用 -batch 選項。本小節典型演示樣例中的命令,能夠用選項?-batch??改造例如以下:
openssl ca?-in?app.csr?-out?app.crt?-cert?CA.crt?-keyfile?CA.key?-days?1826?-policy?policy_anything -batch
?
三、常見問題及其解決
? ? ? ? 留待下次補充。
? ? ? ??
?
------本文由CSDN-蚍蜉撼青松【主頁:http://blog.csdn.net/howeverpf】原創,轉載請註明出處!------
?
使用OpenSSL工具制作X.509證書的方法及其註意事項總結