1. 程式人生 > >靈活多變的keytool和openssl生成證書,應用tomcat和nginx

靈活多變的keytool和openssl生成證書,應用tomcat和nginx

靈活多變的keytool和openssl生成證書,應用tomcat和nginx

文章目錄

前言

一般來說,主流的Web服務軟體,通常都基於兩種基礎密碼庫:OpenSSL和Java。

  • Tomcat、Weblogic、JBoss等,使用Java提供的密碼庫。通過Java的Keytool工具,生成Java Keystore(JKS)格式的證書檔案。Tomcat支援JKS格式證書,從Tomcat7開始也支援PFX格式證書,兩種證書格式任選其一
  • Apache、Nginx等,使用OpenSSL提供的密碼庫,生成PEM、KEY、CRT等格式的證書檔案。
  • IBM的Web服務產品,如Websphere、IBM Http Server(IHS)等,一般使用IBM產品自帶的iKeyman工具,生成KDB格式的證書檔案。
  • 微軟Windows Server中的Internet Information Services(IIS)服務,使用Windows自帶的證書庫生成PFX格式的證書檔案。

什麼是證書?為什麼要使用證書?

對資料進行簽名(加密)是我們在網路中最常見的安全操作。簽名有雙重作用,作用一就是保證資料的完整性,證明資料並非偽造,而且在傳輸的過程中沒有被篡改,作用二就是防止資料的釋出者否認其釋出了該資料。

簽名同時使用了非對稱性加密演算法和訊息摘要演算法,對一塊資料簽名時,會先對這塊資料進行訊息摘要運算生成一個摘要,然後對該摘要使用釋出者的私鑰進行加密。 比如微信公眾平臺開發中最常見的呼叫api介面方法是將引數進行字典序排序,然後將引數名和引數值接成一個字串,組合的字串也就相當於我們這裡說的摘要,然後將摘要用平臺金鑰加密。

接收者(客戶端)接受到資料後,先使用釋出者的公鑰進行解密得到原資料的摘要,再對接收到的資料計算摘要,如果兩個摘要相同,則說明資料沒有被篡改。同時,因為釋出者的私鑰是不公開的,只要接收者通過釋出者的公鑰能成功對資料進行解密,就說明該資料一定來源於該釋出者。

那麼怎麼確定某公鑰一定是屬於某釋出者的呢?這就需要證書了。證書由權威認證機構頒發,其內容包含證書所有者的標識和它的公鑰,並由權威認證機構使用它的私鑰進行簽名。資訊的釋出者通過在網路上釋出證書來公開它的公鑰,該證書由權威認證機構進行簽名,認證機構也是通過釋出它的證書來公開該機構的公鑰,認證機構的證書由更權威的認證機構進行簽名,這樣就形成了證書鏈。證書鏈最頂端的證書稱為根證書,根證書就只有自簽名了。總之,要對網路上傳播的內容進行簽名和認證,就一定會用到證書。關於證書遵循的標準,最流行的是 X.509

證書格式轉換

證書格式的轉換如下圖:

在這裡插入圖片描述

Note: 阿里云云盾證書服務統一使用 PEM 格式的數字證書檔案。

  1. JKS格式證書轉換成PFX格式(jks->pfx)

您可以使用JDK中自帶的Keytool工具,將JKS格式證書檔案轉換成PFX格式。
例如,您可以執行以下命令將server.jks證書檔案轉換成server.pfx證書檔案:

keytool -importkeystore -srckeystore D:\server.jks -destkeystore D:\server.pfx -srcstoretype JKS -deststoretype PKCS12
  1. PFX格式證書轉換為JKS格式

您可以使用JDK中自帶的Keytool工具,將PFX格式證書檔案轉換成JKS格式。
例如,您可以執行以下命令將server.pfx證書檔案轉換成server.jks證書檔案:

keytool -importkeystore -srckeystore D:\server.pfx -destkeystore D:\server.jks  -srcstoretype PKCS12 -deststoretype JKS
  1. PEM/KEY/CRT格式證書轉換為PFX格式

您可以使用 OpenSSL工具,將KEY格式金鑰檔案和CRT格式公鑰檔案轉換成PFX格式證書檔案。
例如,將您的KEY格式金鑰檔案(server.key)和CRT格式公鑰檔案(server.crt)拷貝至OpenSSL工具安裝目錄,使用OpenSSL工具執行以下命令將證書轉換成server.pfx證書檔案:

openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt
  1. PFX轉換為PEM/KEY/CRT

可以使用 OpenSSL工具,將PFX格式證書檔案轉化為KEY格式金鑰檔案和CRT格式公鑰檔案。
例如,將您的PFX格式證書檔案拷貝至OpenSSL安裝目錄,使用OpenSSL工具執行以下命令將證書轉換成server.pem證書檔案,KEY格式金鑰檔案(server.key)和CRT格式公鑰檔案(server.crt):

openssl pkcs12 -in server.pfx -nodes -out server.pem
openssl rsa -in server.pem -out server.key
//此轉換步驟是專用於通過Keytool工具生成私鑰和CSR申請證書檔案的,並且通過此方法您可以在獲取到PEM格式證書公鑰的情況下分離私鑰。
openssl x509 -in server.pem -out server.crt

證書格式

您可以使用以下方法簡單區分帶有後綴副檔名的證書檔案:

  1. *.DER*.CER檔案: 這樣的證書檔案是二進位制格式,只含有證書資訊,不包含私鑰。
  2. *.CRT檔案: 這樣的證書檔案可以是二進位制格式,也可以是文字格式,一般均為文字格式,功能與 *.DER*.CER證書檔案相同。
  3. *.PEM檔案: 這樣的證書檔案一般是文字格式,可以存放證書或私鑰,或者兩者都包含。 *.PEM 檔案如果只包含私鑰,一般用*.KEY檔案代替。
  4. *.PFX*.P12檔案: 這樣的證書檔案是二進位制格式,同時包含證書和私鑰,且一般有密碼保護。
    您也可以使用記事本直接開啟證書檔案。如果顯示的是規則的數字字母,例如:
—–BEGIN CERTIFICATE—–
MIIE5zCCA8+gAwIBAgIQN+whYc2BgzAogau0dc3PtzANBgkqh......
—–END CERTIFICATE—–

那麼,該證書檔案是文字格式的。

如果存在——BEGIN CERTIFICATE——,則說明這是一個證書檔案。
如果存在—–BEGIN RSA PRIVATE KEY—–,則說明這是一個私鑰檔案。

(Java、.Net、Php)語言需要的證書格式並不一致,比如說Java我們採用jks,.Net採用pfx和cer,Php則採用pem和cer

主要分成兩類,其一為金鑰庫檔案格式、其二為證書檔案格式;

金鑰庫檔案格式【Keystore

格式 副檔名 描述 特點
JKS .jks/.ks 【Java Keystore】金鑰庫的Java實現版本,provider為SUN 金鑰庫和私鑰用不同的密碼進行保護
JCEKS .jce JCE Keystore】金鑰庫的JCE實現版本,provider為SUN JCE 相對於JKS安全級別更高,保護Keystore私鑰時採用TripleDES
PKCS12 .p12/.pfx 【PKCS #12】個人資訊交換語法標準 金鑰庫和私鑰用不同的密碼進行保護
JKS .jks/.ks 【Java Keystore】金鑰庫的Java實現版本,provider為SUN 1、包含私鑰、公鑰及其證書\2、金鑰庫和私鑰用相同密碼進行保護

證書檔案格式【Certificate

格式 副檔名 描述 特點
DER .cer/.crt/.rsa 【ASN .1 DER】用於存放證書 不含私鑰、二進位制
PKCS7 .p7b/.p7r 【PKCS #7】加密資訊語法標準 1、p7b以樹狀展示證書鏈,不含私鑰
2、p7r為CA對證書請求籤名的回覆,只能用於匯入
CMS .p7c/.p7m/.p7s 【Cryptographic Message Syntax】 1、p7c只儲存證書2、p7m:signature with enveloped data3、p7s:時間戳簽名檔案
PEM .pem 【Printable Encoded Message】 1、該編碼格式在RFC1421中定義,其實PEM是【Privacy-Enhanced Mail】的簡寫,但他也同樣廣泛運用於金鑰管理2、ASCII檔案3、一般基於base 64編碼
PKCS10 .p10/.csr 【PKCS #10】公鑰加密標準【Certificate Signing Request】 1、證書籤名請求檔案2、ASCII檔案3、CA簽名後以p7r檔案回覆
SPC .pvk/.spc 【Software Publishing Certificate】 微軟公司特有的雙證書檔案格式,經常用於程式碼簽名,其中1、pvk用於儲存私鑰2、spc用於儲存公鑰

jks是JAVA的keytools證書工具支援的證書私鑰格式。
pfx是微軟支援的私鑰格式。
cer是證書的公鑰。
如果是你私人要備份證書的話記得一定要備份成jks或者pfx格式,否則恢復不了。
簡單來說,cer就是你們家郵箱的地址,你可以把這個地址給很多人讓他們往裡面發信。
pfx或jks就是你家郵箱的鑰匙,別人有了這個就可以冒充你去你家郵箱看信,你丟了這個也沒法開郵箱了。

keytool是什麼?

Keytool 是一個Java 資料證書的管理工具 ,Keytool 將金鑰(key)和證書(certificates)存在一個稱為keystore的檔案中 在keystore裡,包含兩種資料:
金鑰實體(Key entity)——金鑰(secret key)又或者是私鑰和配對公鑰(採用非對稱加密)
可信任的證書實體(trusted certificate entries)——只包含公鑰
而我們常說的證書就是就是上面說的公鑰,公鑰是公開給其它人使用的。也就是常用說的搬發證書。

keytool的幫助命令

keytool -help

結果如下

PS D:\keys> keytool -help
金鑰和證書管理工具

命令:

 -certreq            生成證書請求
 -changealias        更改條目的別名
 -delete             刪除條目
 -exportcert         匯出證書
 -genkeypair         生成金鑰對
 -genseckey          生成金鑰
 -gencert            根據證書請求生成證書
 -importcert         匯入證書或證書鏈
 -importpass         匯入口令
 -importkeystore     從其他金鑰庫匯入一個或所有條目
 -keypasswd          更改條目的金鑰口令
 -list               列出金鑰庫中的條目
 -printcert          列印證書內容
 -printcertreq       列印證書請求的內容
 -printcrl           列印 CRL 檔案的內容
 -storepasswd        更改金鑰庫的儲存口令

使用 "keytool -command_name -help" 獲取 command_name 的用法

檢視某個命令幫助

keytool -genkeypair

keytool官方文件

主要格式

keytool 採用 keystore 檔案來儲存金鑰及證書,其中可包括私鑰、信任證書;
keystore 檔案主要使用 JKS格式(也可支援其他格式),帶金鑰儲存;其中私鑰的儲存也有獨立的密碼;
通過keytool -genkeypair -storetype 格式指定

其它還包括jceks,jks,dks,pkcs11,pkcs12。

test.keystore和test.jks區別

keytool -genkeypair -alias serverkey -keystore server.keystore -storetype jks

與下面和是等價的,都是jks格式金鑰檔案。

keytool -genkeypair -alias serverkey -keystore server.jks

keytool生成tomcat證書

Tomcat支援JKS格式證書,從Tomcat7開始也支援PFX格式證書,兩種證書格式任選其一。

生成私鑰和證書

keytool -genkeypair -alias dongli -keystore dongli.jks -keypass 123456 -storepass 123456  -keyalg RSA -keysize 2048 -validity 365

storepass:keystore 檔案儲存密碼
keypass: 私鑰加解密密碼
alias:實體別名(包括證書私鑰)
keyalt:採用公鑰演算法,預設是DSA,還有RSA演算法可選
keysize:金鑰長度(DSA演算法對應的預設演算法是sha1withDSA,不支援2048長度,此時需指定RSA)
validity:有效期(至少設一年,你也不想經常要升級證書吧)
keystore:指定keystore檔案

提示輸入的姓名和姓氏輸入域名,比較http://192.168.1.243(假設你在區域網使用https協議)

擴充套件
如果想建立pkcs12格式金鑰檔案

keytool -genkeypair -alias dongli -keystore dongli.jks -keypass 123456 -storetype pkcs12  -storepass 123456  -keyalg RSA -keysize 2048 -validity 365

檢視證書詳情

keytool -list -keystore dongli.jks  -storepass 123456 

結果如下

PS D:\keys> keytool -list -keystore dongli.jks  -storepass 123456
金鑰庫型別: jks
金鑰庫提供方: SUN

您的金鑰庫包含 1 個條目

dongli, 2018-10-24, PrivateKeyEntry,
證書指紋 (SHA1): 20:84:B4:01:A0:2B:54:48:8D:F5:10:27:7F:93:D5:11:F9:A8:1C:79

Warning:
JKS 金鑰庫使用專用格式。建議使用 "keytool -importkeystore -srckeystore dongli.jks -destkeystore dongli.jks -deststoretype pkcs12" 遷移到行業標準格式 PKCS12。

加上-v選項可檢視更詳細資訊keytool -list -v -keystore dongli.jks -storepass 123456

jks轉成pkcs12格式證書

其實上面命令列已經提示了

keytool -importkeystore -srckeystore dongli.jks -destkeystore dongli.jks -deststoretype pkcs12

匯出證書

匯出證書就是將匯出公鑰檔案

keytool -exportcert -keystore dongli.jks -file dongli.cer -alias dongli -storepass 123456

注意:-alias dongli,為什麼要別名?因為dongli.jks裡可以儲存多對公私鑰檔案,它們之間是通過別名區分的,所以這裡是通過別名指定匯出的是金鑰檔案裡別名是dongli的公鑰證書
此時匯出的證書為DER編碼格式,-rfc選項,可輸出pem編碼格式的證書

匯入證書

匯入證書其實是在客戶機器上使用的。如果是CA申請的證書是自動完成的。其實如果是官方認證過的證書,這步可以省略。

  • 雙擊dongli.cer完成匯入操作
  • keytool -importcert -keystore client_trust.keystore -file dongli.cer -alias client_trust_server -storepass 123456。結果如下
PS D:\keys> keytool -importcert -keystore client_trust.keystore  -file dongli.cer -alias client_trust_server -storepass
123456
所有者: CN=http://192.168.1.243, OU=http://192.168.1.243, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
釋出者: CN=http://192.168.1.243, OU=http://192.168.1.243, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
序列號: 466adb68
有效期為 Wed Oct 24 11:15:01 CST 2018 至 Thu Oct 24 11:15:01 CST 2019
證書指紋:
         MD5:  A0:2D:00:2F:97:3D:84:64:E2:F7:C0:17:50:F1:24:8D
         SHA1: 20:84:B4:01:A0:2B:54:48:8D:F5:10:27:7F:93:D5:11:F9:A8:1C:79
         SHA256: FA:DF:E3:11:AF:1B:BA:3B:59:1D:39:44:EB:62:FA:EA:76:56:A2:6B:D9:26:33:68:D2:D8:49:E0:0D:15:BD:C4
簽名演算法名稱: SHA256withRSA
主體公共金鑰演算法: 2048 位 RSA 金鑰
版本: 3

擴充套件:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: D7 07 91 5D 1F 1A C8 DB   EB 9E 10 76 63 4B 5A DE  ...].......vcKZ.
0010: 2B 01 89 2E                                        +...
]
]

是否信任此證書? [否]:  y
證書已新增到金鑰庫中

證書安裝

PFX證書安裝

找到安裝Tomcat目錄下該檔案server.xml,一般預設路徑都是在 conf 資料夾中。找到 <Connection port="8443"標籤,增加如下屬性:

keystoreFile="cert/214936953020033.pfx"
keystoreType="PKCS12"
#此處的證書密碼,請參考附件中的密碼檔案或在第1步中設定的密碼
keystorePass="證書密碼"

完整的配置如下,其中port屬性根據實際情況修改:

<Connector port="8443"
    protocol="HTTP/1.1"
    SSLEnabled="true"
    scheme="https"
    secure="true"
    keystoreFile="cert/214936953020033.pfx"
    keystoreType="PKCS12"
    keystorePass="證書密碼"
    clientAuth="false"
    SSLProtocol="TLSv1+TLSv1.1+TLSv1.2"
    ciphers="TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256"/>

JKS證書安裝

  • 如果只能pfx格式的檔案,使用java jdk將PFX格式證書轉換為JKS格式證書(windows環境注意在%JAVA_HOME%/jdk/bin目錄下執行)
keytool -importkeystore -srckeystore 214936953020033.pfx -destkeystore your-name.jks -srcstoretype PKCS12 -deststoretype JKS
  • 找到安裝 Tomcat 目錄下該檔案Server.xml,一般預設路徑都是在 conf 資料夾中。找到 <Connection port="8443"標籤,增加如下屬性:
keystoreFile="cert/your-name.jks"
keystorePass="證書密碼"

完整的配置如下,其中port屬性根據實際情況修改:

<Connector port="8443"
    protocol="HTTP/1.1"
    SSLEnabled="true"
    scheme="https"
    secure="true"
    keystoreFile="cert/your-name.jks"
    keystorePass="證書密碼"
    clientAuth="false"
    SSLProtocol="TLSv1+TLSv1.1+TLSv1.2"
    ciphers="TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256"/>

注意:不要直接拷貝所有配置,只需新增 keystoreFile,keystorePass等引數即可,其它引數請根據自己的實際情況修改

nginx證書

nginx證書安裝只要key和pem檔案

  • 在Nginx的安裝目錄下建立cert目錄,並且將下載的全部檔案拷貝到cert目錄中。如果申請證書時是自己建立的CSR檔案,請將對應的私鑰檔案放到cert目錄下並且命名為test.key
  • 開啟 Nginx 安裝目錄下 conf 目錄中的 nginx.conf 檔案,找到:
# HTTPS server
# #server {
# listen 443;
# server_name localhost;
# ssl on;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_timeout 5m;
# ssl_protocols SSLv2 SSLv3 TLSv1;
# ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
# ssl_prefer_server_ciphers on;
# location / {
#
#
#}
#}

修改為 (以下屬性中ssl開頭的屬性與證書配置有直接關係,其它屬性請結合自己的實際情況複製或調整) :

server {
    listen 443;
    server_name localhost;
    ssl on;
    root html;
    index index.html index.htm;
    ssl_certificate   cert/214936953020033.pem;
    ssl_certificate_key  cert/214936953020033.key;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    location / {
        root html;
        index index.html index.htm;
    }
}

儲存退出,重啟 Nginx。

指令碼

set pwd=123456
set name=dongli
set dd=%cd%

:: 生成jks
rmdir /s /q jks
mkdir jks
cd jks
keytool -genkeypair -alias %name% -keystore %name%.jks -storetype pkcs12 -keypass %pwd% -storepass %pwd%  -keyalg RSA -keysize 2048 -validity 365 -dname "CN=http://192.168.1.243,OU=xx,O=dy, L=nb,ST=zj,C=china"

keytool -exportcert -keystore %name%.jks -file %name%.cer -alias %name% -storepass %pwd%
cd %dd%

:: 轉換jks->pfx
rmdir /s /q pfx
mkdir pfx
keytool -importkeystore -srckeystore %dd%/jks/%name%.jks -destkeystore %dd%/pfx/%name%.pfx -srcstoretype PKCS12 -deststoretype PKCS12 -srcstorepass %pwd% -deststorepass %pwd%



:: 轉換pfx->pem/key
rmdir /s /q pem
mkdir pem
openssl pkcs12 -in %dd%/pfx/%name%.pfx -nodes -out %dd%/pem/%name%.pem -password pass:%pwd%
openssl rsa -in %dd%/pem/%name%.pem -out %dd%/pem/%name%.key
cd %dd%
keytool -list -v -keystore %dd%/jks/%name%.jks -storepass %pwd%