证书可以通过openssl或者keytool创建,在本篇文章中,只介绍openssl。

openssl 生成证书

申请操作流程

  1. 生成ca证书私钥, 文件名:ca.key
  2. 生成ca证书,文件名:ca.crt
  3. 生成Server/Client 证书私钥,文件名:server.key, client.key
  4. 生成Server/Client 证书签名请求,文件名:server.csr, client.csr
  5. 生成v3扩展文件(可选),文件名:v3.ext
  6. 生成Server/Client 证书,文件名:server.crt, client.crt

示意图如下:
在这里插入图片描述

证书签名请求的机构信息

在生成证书签名请求(csr)时,需要补充机构信息,如下:

参数名称subject 简写参数值示例
Country NameC国家代码比如中国就是CN
State or Province NameST省名称Zhejiang
Locality NameL城市名称Hangzhou
Organization NameO机构名称
Organizational Unit NameOU机构单位名称
Common NameCN重点参数:授权给什么,因为机构是根节点所以是授权给自己域名:www.test.com
IP:xxx.xxx.xxx.xxx
Email AddressemailAddress邮件地址

生成证书

通过下两种方法创建证书后,最后得到有用的文件分别为:

文件
服务器端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 36500


8.生成服务器端的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.crt


12.备份服务器私钥
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 JKS

20. 转换客户端 的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

解决办法:

  1. 规避措施:
    应用程序启动时,在启动参数里加上如下参数,不进行校验是否为CA
    -Djdk.security.allowNonCaAnchor=true
  2. 根本解决方法:
    在生成CA证书时明确添加是否为CA的标识 -ext BasicConstraints=ca:true
  3. 使用上面的两种方法生成ca.crt

参考

局域网内搭建浏览器可信任的SSL证书
openssl创建CA证书教程
生成可信任的https证书
基于Netty的MQTT Server实现并支持SSL
记一次TrustAnchor with subject异常解决
手动实现CA数字认证(java)
java编程方式生成CA证书

GitHub 加速计划 / ope / openssl
20
1
下载
传输层安全性/安全套接层及其加密库
最近提交(Master分支:3 个月前 )
4f37e543 Recent test additions have increased the number of jobs spawned by the interop runner test which exceeds the maximum allowed. This occurs because the matrix expands to: 7 server elements 6 client elements 7 tests 2 test steps (client interop and server interop Because of how github ci does matrix expansion, this results in 2 * 7 * 7 * 6 = 588 But most of those are invalid because each of the 2 steps only considers either the client or server elements, and so get rerun multiple times Alter the steps to be individual jobs, each with their own reduced matrix to only run each relevant test once, limiting our job count to at most 49 jobs. Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Viktor Dukhovni <viktor@openssl.org> Reviewed-by: Saša Nedvědický <sashan@openssl.org> (Merged from https://github.com/openssl/openssl/pull/26275) 3 天前
c93f4a1e This makes `ikmlen` have a length of at least `Nsk`. Closes #26213 Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com> Reviewed-by: Viktor Dukhovni <viktor@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/26254) 3 天前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐