• mTLS: openssl创建CA证书


    证书可以通过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
    
    • 1

    生成ca证书,文件名:ca.crt

    使用下面命令生成ca根证书,输出一个有效期36500天的ca.crt文件

    openssl req -new -x509 -key ca.key -out ca.crt -days 36500
    
    • 1

    上面的命令需要在命令窗口中补充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"
    
    
    • 1
    • 2

    注意: 如果ca.crt过期,新旧ca.crt的subject参数信息需要完全一样,否则对那些由旧ca.crt签名生成的证书进行校验时会失败报错。

    生成Server/Client 证书私钥,文件名:server.key, client.key

    生成服务器端私钥

    openssl genrsa -out server.key 2048
    
    • 1

    生成客户端私钥

    openssl genrsa -out client.key 2048
    
    • 1

    生成Server/Client 证书签名请求,文件名:server.csr, client.csr

    生成Server证书:
    生成服务器端的csr文件,为生成服务器证书做准备

    openssl req -new -key server.key -out server.csr
    
    • 1

    或者添加-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"
    
    • 1

    生成Client证书:
    生成client 端csr文件,为生成client证书做准备

    openssl req -new -key client.key -out client.csr
    
    • 1

    或者添加-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"
    
    • 1

    生成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
    
    • 1

    生成client 端证书crt文件

    openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt -days 36500
    
    • 1

    将key转换为PK8

    转换服务端key为PK8

    openssl pkcs8 -topk8 -in server.key -out pkcs8_server.key -nocrypt
    
    • 1

    转换客户端key为PK8

    openssl pkcs8 -topk8 -in client.key -out pkcs8_client.key -nocrypt
    
    • 1

    私钥有密码

    生成ca的私钥和证书, 文件名:ca.key, ca.crt

    openssl req -new -x509 -keyout ca.key -out ca.crt -days 36500
    
    • 1

    快速生成方法(注意修改-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"
    
    • 1

    注意:使用这种方式需要记好私钥密码,尤其是ca.key的密码, 如果ca.crt过期,续期生成新的ca.crt时需要用到。

    生成Server/Client 证书私钥,文件名:server.key, client.key

    生成服务端和客户端私钥

    openssl genrsa -des3 -out server.key 1024
    
    • 1

    生成客户端私钥

    openssl genrsa -des3 -out client.key 1024
    
    • 1

    生成Server/Client 证书签名请求,文件名:server.csr, client.csr

    根据 server.key 生成服务端的server.csr 文件

    openssl req -new -key server.key -out server.csr
    
    • 1

    根据 client.key 生成客户端的client.csr 文件

    openssl req -new -key client.key -out client.csr
    
    • 1

    如果觉得上面的命令麻烦的话, 可以添加-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"
    
    • 1

    快速生成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"
    
    • 1

    生成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
    
    • 1

    根据 ca 证书签名申请 client.csr 生成客户端的x509 证书:

    openssl x509 -req -days 36500 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt
    
    • 1

    #如果需要和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")
    
    • 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")
    
    • 1

    将key转换为不需要密码的PK8

    转换服务端key为PK8

    openssl pkcs8 -topk8 -in server.key -out pkcs8_server.key -nocrypt
    
    • 1

    转换客户端key为PK8

    openssl pkcs8 -topk8 -in client.key -out pkcs8_client.key -nocrypt
    
    • 1

    完整操作命令

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    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
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    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
    • 2

    解决办法:

    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证书

  • 相关阅读:
    本次CTF·泰山杯网络安全的基础知识部分
    安卓APP源码和报告——学生信息管理系统
    python多线程系列—Queue对象(五)
    【Spring】数据导出为Excel的接口报java.io.IOException: UT010029: Stream is closed错误
    【文末送书】深入浅出嵌入式虚拟机原理
    基于单片机的步进电机驱动控制系统的设计与实现
    10 个高质量 AI 助手工具站点,你值得拥有的哦
    Leetcode 142. 环形链表 II
    Android开发学习日记--利用元数据传递配置文件
    Blender中的4种视图着色模式
  • 原文地址:https://blog.csdn.net/Mr_rain/article/details/136407861