證書可以通過openssl或者keytool創建,在本篇文章中,只介紹openssl。
openssl 生成證書
申請操作流程
- 生成ca證書私鑰, 文件名:ca.key
- 生成ca證書,文件名:ca.crt
- 生成Server/Client 證書私鑰,文件名:server.key, client.key
- 生成Server/Client 證書簽名請求,文件名:server.csr, client.csr
- 生成v3擴展文件(可選),文件名:v3.ext
- 生成Server/Client 證書,文件名:server.crt, client.crt
示意圖如下:
證書簽名請求的機構信息
在生成證書簽名請求(csr)時,需要補充機構信息,如下:
參數名稱 | subject 簡寫 | 參數值 | 示例 |
---|---|---|---|
Country Name | C | 國家代碼 | 比如中國就是CN |
State or Province Name | ST | 省名稱 | Zhejiang |
Locality Name | L | 城市名稱 | Hangzhou |
Organization Name | O | 機構名稱 | |
Organizational Unit Name | OU | 機構單位名稱 | |
Common Name | CN | 重點參數:授權給什么,因為機構是根節點所以是授權給自己 | 域名:www.test.com IP:xxx.xxx.xxx.xxx |
Email Address | emailAddress | 郵件地址 |
生成證書
通過下兩種方法創建證書后,最后得到有用的文件分別為:
端 | 文件 |
---|---|
服務器端 | ca.crt、server.crt、(pkcs8_server.key 或 server.key) |
客戶端端 | ca.crt、client.crt、(pkcs8_client.key 或 client.ke) |
私鑰無密碼
生成ca證書私鑰, 文件名:ca.key
執行下面的命令,會輸出ca.key文件
openssl genrsa -out ca.key 2048
生成ca證書,文件名:ca.crt
使用下面命令生成ca根證書,輸出一個有效期36500天的ca.crt文件
openssl req -new -x509 -key ca.key -out ca.crt -days 36500
上面的命令需要在命令窗口中補充subject信息(注意修改-subj 中的參數),使用下面的命令直接將subject信息傳入,無需在命令窗口慢慢補充
openssl req -new -x509 -key ca.key -out ca.crt -days 36500 -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Organization Company/OU=Organizational Unit Name/CN=www.ts.com/emailAddress=m@ts.com sign CA"
注意: 如果ca.crt過期,新舊ca.crt的subject參數信息需要完全一樣,否則對那些由舊ca.crt簽名生成的證書進行校驗時會失敗報錯。
生成Server/Client 證書私鑰,文件名:server.key, client.key
生成服務器端私鑰
openssl genrsa -out server.key 2048
生成客戶端私鑰
openssl genrsa -out client.key 2048
生成Server/Client 證書簽名請求,文件名:server.csr, client.csr
生成Server證書:
生成服務器端的csr文件,為生成服務器證書做準備
openssl req -new -key server.key -out server.csr
或者添加-subj參考快速生成服務器端的csr文件(注意修改-subj 中的參數):
openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Server Company/OU=Server Unit Name/CN=ser.ts.com/emailAddress=ser@ts.com"
生成Client證書:
生成client 端csr文件,為生成client證書做準備
openssl req -new -key client.key -out client.csr
或者添加-subj參考快速生成client端的csr文件(注意修改-subj 中的參數):
openssl req -new -key client.key -out client.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Client Company/OU=Client Unit Name/CN=cli.ts.com/emailAddress=cli@ts.com"
生成Server/Client 證書,文件名:server.crt, client.crt
生成服務器端證書crt文件
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt -days 36500
生成client 端證書crt文件
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt -days 36500
將key轉換為PK8
轉換服務端key為PK8
openssl pkcs8 -topk8 -in server.key -out pkcs8_server.key -nocrypt
轉換客戶端key為PK8
openssl pkcs8 -topk8 -in client.key -out pkcs8_client.key -nocrypt
私鑰有密碼
生成ca的私鑰和證書, 文件名:ca.key, ca.crt
openssl req -new -x509 -keyout ca.key -out ca.crt -days 36500
快速生成方法(注意修改-subj 中的參數):
openssl req -new -x509 -keyout ca.key -out ca.crt -days 36500 -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Organization Company/OU=Organizational Unit Name/CN=www.ts.com/emailAddress=m@ts.com sign CA"
注意:使用這種方式需要記好私鑰密碼,尤其是ca.key的密碼, 如果ca.crt過期,續期生成新的ca.crt時需要用到。
生成Server/Client 證書私鑰,文件名:server.key, client.key
生成服務端和客戶端私鑰
openssl genrsa -des3 -out server.key 1024
生成客戶端私鑰
openssl genrsa -des3 -out client.key 1024
生成Server/Client 證書簽名請求,文件名:server.csr, client.csr
根據 server.key 生成服務端的server.csr 文件
openssl req -new -key server.key -out server.csr
根據 client.key 生成客戶端的client.csr 文件
openssl req -new -key client.key -out client.csr
如果覺得上面的命令麻煩的話, 可以添加-subj參數(注意修改-subj 中的參數),快速生成。
快速生成server.csr:
openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Server Company/OU=Server Unit Name/CN=ser.ts.com/emailAddress=ser@ts.com"
快速生成client.csr
openssl req -new -key client.key -out client.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Client Company/OU=Client Unit Name/CN=cli.ts.com/emailAddress=cli@ts.com"
生成Server/Client 證書,文件名:server.crt, client.crt
根據 ca 證書簽名申請 server.csr 生成 服務端的x509 證書:
openssl x509 -req -days 36500 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
根據 ca 證書簽名申請 client.csr 生成客戶端的x509 證書:
openssl x509 -req -days 36500 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt
#如果需要和ip綁定則加上參數。
服務端-server.crt
openssl x509 -req -days 36500 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -extfile <(printf "subjectAltName=IP:127.0.0.1")
客戶端-client.crt
openssl x509 -req -days 36500 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -extfile <(printf "subjectAltName=IP:127.0.0.1")
將key轉換為不需要密碼的PK8
轉換服務端key為PK8
openssl pkcs8 -topk8 -in server.key -out pkcs8_server.key -nocrypt
轉換客戶端key為PK8
openssl pkcs8 -topk8 -in client.key -out pkcs8_client.key -nocrypt
完整操作命令
openssl 私鑰無密碼
mtls證書生成#生成ca證書,在目錄中輸出 ca.key 和 ca.crt 文件
openssl req -new -x509 -keyout ca.key -out ca.crt -days 36500
openssl req -new -x509 -keyout ca.key -out ca.crt#生成 CA 私鑰
openssl genrsa -out ca.key 2048
#生成ca證書,在目錄中輸出 ca.crt 文件
openssl req -new -x509 -key ca.key -out ca.crt -days 36500
#生成ca證書,在目錄中輸出 ca.crt 文件(直接填充subject參數), -subj參數 "C=cn, ST=zj, L=hz, O=ser-ts, OU=ser-ts-un, CN=ser.ts.com, emailAddress=ser@ts.com"
openssl req -new -x509 -key ca.key -out ca.crt -days 36500 -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Organization Company/OU=Organizational Unit Name/CN=www.ts.com/emailAddress=m@ts.com sign CA"openssl req -new -x509 -key ca.key -out ca.crt -days 36500 -sha256 -extensions v3_ca -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Organization Company/OU=Organizational Unit Name/CN=www.ts.com/emailAddress=m@ts.com sign CA"#生成CA的csr文件,保存必要信息;生成CA的證書文件crt文件
#該命令生成的ca.crt文件在mtls場景會報:io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: sun.security.validator.ValidatorException: TrustAnchor with subject "CN=xxx, OU=xx, O=xx, L=hz, ST=zj, C=cn" is not a CA certificate
#以上異常產生的具體原因本人暫時未知
---
openssl req -new -key ca.key -out ca.csr
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt
---#
#生成服務器端私鑰
openssl genrsa -out server.key 2048
#生成服務器端公鑰
openssl rsa -in server.key -pubout -out server.pem
#生成服務器端的csr文件,為生成服務器證書做準備
openssl req -new -key server.key -out server.csr
#生成服務器端的csr文件(直接填充subject參數)
openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Server Company/OU=Server Unit Name/CN=ser.ts.com/emailAddress=ser@ts.com"
#生成服務器端證書crt文件
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt -days 36500
#轉換服務端key為PK8
openssl pkcs8 -topk8 -in server.key -out pkcs8_server.key -nocrypt#生成客戶端私鑰
openssl genrsa -out client.key 2048
#生成客戶端公鑰
openssl rsa -in client.key -pubout -out client.pem
#生成client 端csr文件,為生成client證書做準備
openssl req -new -key client.key -out client.csr
#生成client 端csr文件(直接填充subject參數)
openssl req -new -key client.key -out client.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Client Company/OU=Client Unit Name/CN=cli.ts.com/emailAddress=cli@ts.com"
#生成client 端證書crt文件
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt -days 36500
#轉換客戶端key為PK8
openssl pkcs8 -topk8 -in client.key -out pkcs8_client.key -nocrypt
openssl 私鑰有密碼
#生成ca證書,輸出 ca.key 和 ca.crt 文件
openssl req -new -x509 -keyout ca.key -out ca.crt -days 36500
#生成ca證書,輸出 ca.key 和 ca.crt 文件
openssl req -new -x509 -keyout ca.key -out ca.crt -days 36500 -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Organization Company/OU=Organizational Unit Name/CN=www.ts.com/emailAddress=m@ts.com sign CA"#生成服務端和客戶端私鑰
openssl genrsa -des3 -out server.key 1024
openssl genrsa -des3 -out client.key 1024#根據 key 生成 csr 文件
openssl req -new -key server.key -out server.csr
openssl req -new -key client.key -out client.csr
#根據 key 生成 csr 文件,快速生成csr文件
openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Server Company/OU=Server Unit Name/CN=ser.ts.com/emailAddress=ser@ts.com"
openssl req -new -key client.key -out client.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Client Company/OU=Client Unit Name/CN=cli.ts.com/emailAddress=cli@ts.com"#根據 ca 證書 server.csr 和 client.csr 生成 x509 證書
openssl x509 -req -days 36500 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
openssl x509 -req -days 36500 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt
#如果需要和ip綁定則加上參數
openssl x509 -req -days 36500 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -extfile <(printf "subjectAltName=IP:127.0.0.1")
openssl x509 -req -days 36500 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -extfile <(printf "subjectAltName=IP:127.0.0.1")#將 key 文件進行 PKCS#8 編碼
openssl pkcs8 -topk8 -in server.key -out pkcs8_server.key -nocrypt
openssl pkcs8 -topk8 -in client.key -out pkcs8_client.key -nocrypt
openssl 生成證書以及證書轉換
1.生成服務器端私鑰
openssl genrsa -out server.key 2048
2.生成服務器端公鑰
openssl rsa -in server.key -pubout -out server.pem
3.生成客戶端私鑰
openssl genrsa -out client.key 2048
4.生成客戶端公鑰
openssl rsa -in client.key -pubout -out client.pem
5.生成 CA 私鑰
openssl genrsa -out ca.key 2048
6.生成CA的csr文件,保存必要信息
openssl req -new -key ca.key -out ca.csr
7. 生成CA的證書文件crt文件
#這個命令生成ca.crt文件會在mtls場景會有信任問題,建議使用后面的命令
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt
#這段命令生成的ca.crt在mtls場景可以正常使用
openssl req -new -x509 -key ca.key -out ca.crt -days 365008.生成服務器端的csr文件,為生成服務器證書做準備
openssl req -new -key server.key -out server.csr
9.生成服務器端證書crt文件
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
10.生成client 端csr文件,為生成client證書做準備
openssl req -new -key client.key -out client.csr
11.生成client 端證書crt文件
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt12.備份服務器私鑰
openssl rsa -in server.key -out server_nopwd.key
13.生成服務器端證書
openssl x509 -req -days 365 -in server.csr -signkey server_nopwd.key -out server.crt
14.轉換服務端key為PK8
openssl pkcs8 -topk8 -in server.key -out pkcs8_server.key -nocrypt
15.轉換客戶端key為PK8
openssl pkcs8 -topk8 -in client.key -out pkcs8_client.key -nocrypt
16.轉換ca 的cert+key為pfx
openssl pkcs12 -export -in ca.crt -inkey ca.key -out ca.pfx
17.轉換ca的 pfx為jks
keytool -importkeystore -srckeystore ca.pfx -destkeystore ca.jks -srcstoretype PKCS12 -deststoretype JKS
18. 轉換服務端 的cert+key為pfx
openssl pkcs12 -export -in server.crt -inkey server.key -out server.pfx
19. 轉換服務端的 pfx為jks
keytool -importkeystore -srckeystore server.pfx -destkeystore server.jks -srcstoretype PKCS12 -deststoretype JKS20. 轉換客戶端 的cert+key為pfx
openssl pkcs12 -export -in client.crt -inkey client.key -out client.pfx
21. 轉換客戶端的 pfx為jks
keytool -importkeystore -srckeystore client.pfx -destkeystore client.jks -srcstoretype PKCS12 -deststoretype JKS
SSLHandshakeException:TrustAnchor with subject “CN=xxx, OU=xx, O=xx, L=hz, ST=zj, C=cn” is not a CA certificate 解決辦法:
詳細錯誤信息:
io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: sun.security.validator.ValidatorException: TrustAnchor with subject "CN=xxx, OU=xx, O=xx, L=hz, ST=zj, C=cn" is not a CA certificate
原因:
使用下面的命令生成ca.crt
openssl req -new -key ca.key -out ca.csr
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt
解決辦法:
- 規避措施:
應用程序啟動時,在啟動參數里加上如下參數,不進行校驗是否為CA
-Djdk.security.allowNonCaAnchor=true - 根本解決方法:
在生成CA證書時明確添加是否為CA的標識 -ext BasicConstraints=ca:true - 使用上面的兩種方法生成ca.crt
參考
局域網內搭建瀏覽器可信任的SSL證書
openssl創建CA證書教程
生成可信任的https證書
基于Netty的MQTT Server實現并支持SSL
記一次TrustAnchor with subject異常解決
手動實現CA數字認證(java)
java編程方式生成CA證書