admin管理员组

文章数量:1651307

文章目录

  • 一、PKI、CA、TLS/SSL、OpenSSL等概念及原理
  • 二、基于OpenSSL生成自签名证书
    • 1、明确X509证书标准的两种编码格式PEM和DER
    • 2、证书相关文件常用扩展名
    • 3、实战
    • 4. 查看密钥
      • 4.1 用openssl命令查看私钥的明细
      • 4.2 由私钥生成对应的公钥
    • 5. 查看证书
      • 5.1 查看完整的证书
      • 5.2 查看证书序列号
      • 5.3 查看公钥
      • 5.4 查看证书有效期
    • 6. 使用公钥对明文进行加密/解密
      • 使用公钥对明文进行加密
      • 解密,使用私钥解密
    • 7 利用CA校验证书
  • 三、WebSocket基于TLS/SSL双向认证通信(Python示例)
  • 参考

相关文章:
//-----------Java SSL begin----------------------
【ssl认证、证书】SSL双向认证和SSL单向认证的区别(示意图)
【ssl认证、证书】java中的ssl语法API说明(SSLContext)、与keytool 工具的联系
【ssl认证、证书】SSL双向认证java实战、keytool创建证书
【ssl认证、证书】Wireshark抓包分析
【ssl认证、证书】 查看keystore文件内容
//------------Java SSL end--------------------------

//-----------下面的是CA证书和openssl相关的知识--------------
【ssl认证、证书】TLS/SSL双向认证概念、openssl genrsa示例
【ssl认证、证书】openssl genrsa 命令详解
【ssl认证、证书】SSL 证书基本概念、证书格式、openssl和keytool的区别

一、PKI、CA、TLS/SSL、OpenSSL等概念及原理

  • CA 证书签发机构,自己持有私钥,创建根证书,并把根证书发送给操作系统厂商,内置于操作系统中。CA利用根证书和私钥,签发企业证书
  • TLS/SSL 是认证协议,https采用这种协议,可以保证通信安全
  • OpenSSL 是生成证书、根证书、数字签名的工具包

二、基于OpenSSL生成自签名证书

1、明确X509证书标准的两种编码格式PEM和DER

  • PEM(Privacy Enhanced Mail):内容是Base64编码的ASCII码文件,通常用于证书颁发机构(Certificate Authorities,CA),扩展名可为.pem/.crt/.cer/.key。纯文本以"-----BEGIN XXX-----" 和 "-----END XXX-----"作开头和结尾。服务器认证证书,中级认证证书(可理解为公钥)和私钥都可以储存为PEM格式。Apache和类似的服务器使用PEM格式证书。
  • DER(Distinguished Encoding Rules):使用二进制,扩展名为.der,但也经常使用.cer用作扩展名,所有类型的认证证书和私钥都可以存储为DER格式。Java是其典型使用平台。

2、证书相关文件常用扩展名

注意:这个扩展名是随便叫的,你叫.txt也行,这里是为了规范使用,便于识别,尽量采用下面标准后缀

  • CRT :多用于*NIX系统,多数使用PEM编码,DER编码也有使用;
  • CER :多用于Windows系统,多数使用DER编码,PEM编码也有使用;
  • KEY:通常用于存放公钥或者私钥,非X509证书,PEM/DER编码均有;
  • CSR(Certificate Signing Request):证书签名请求,不是证书,用于证书颁发机构申请签名证书,是一个公钥和附加信息,在生成CSR时,还会生成一个私钥;
  • PFX/P12(predecessor of PKCS#12):CRT和KEY存在一个PFX文件中,通常会有一个”提取密码“,用于提取证书内容,使用的DER编码;
  • JKS (Java Key Storage):Java的专利,与OpenSSL关系不大,使用专用工具keytool生成具,可将PFX转为JKS。

3、实战

使用openssl自签名产生SSL证书过程如下图:

OpenSSL执行过程:

//1、生成CA秘钥

openssl genrsa  -out ca.key 2048

查看ca.key的内容:

[root@paas-controller-3:/home/ubuntu/test2]$ cat ca.key
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA2CYa3BH2Neb9fuA52lJQs336WLkM35oZCtOuVQcekxhVP/h1
gryKI2ens5uqxdlo1BX7IBDCi77D+kIS6LTuoyWO2d0zaowZFX9xzwd83CkJ8vPx
aCCAfWgRvFzFHjdR0aG+TnnkAID4VrrBqFMKeX079/hUQ4kl0pyn7BeB70dle80J
DVl78IIp5JW5HqzGrnf5rsX1kjgyWtRfCjk9AjZ7P0+TWQMqg2cNy7v8CWpKasUt
/q+9PPq1eQQLeOkc0s0B1iIisGZ4IxvTDtBMYyXjpygaXrORJcp1/rXSFExLoVcH
MOTS0c5Zws7+nn2RpVvXUyMKeMtgYo1y/LN+6QIDAQABAoIBADWWfOJCsb/7XK2v
+afe8JMPkJmeh0qIcdz1TitWcIYXaktJ1hhrlfPhJvqohVY36H1sVa5FeXYb/Yp2
ByoacW+RSDFLXgv0X+OsjRK+0H3kzsqlIByosjJlMsB4X4Z2QJqwdvYN0jEtyGP4
OTr6G4azPcLklj+IKRBmNluaGGSx4goToJHLCU8IPvwmViQgNh+qm/fI8ekGycqW
TseH9H4DdTIkMOJtsaX2ZBgXqsMzPYWfRPBdkP8FakFw291HTyeUytPAeqAcWcg0
z/ebdscy51dnJ2Ycdj2vpbtT6PqX2OUek7vkVuTAf8IgTpBsc+E5lrx1gtV/Sep3
+R8mMAECgYEA82E9ezod+08W9ovmpJEApPSPCU05LUbgPXt05Ro3gznRHhwEJyNq
3ZdSS0ddizW6DwPn8zI7H1t6s3IGU9c7NE1tUNNvK/axkTMYXo5ONYbG6aW75Tk7
+rMemQ1GTBR2RUqKmcZPJZH2lrsZuq35cE9Fi3pzrrLqcMLIRw6wckECgYEA41ti
o8w+OgMUgxCAaDWXjP5XbJ/90bd68/fzTpyVg72uzFk4d9POLx4e7+rpTHr7uO4p
ksjjAwYUF5loZRnAXgN740tgLUtOZYrSCs45gxe2WYMl5IUTT/RHunxQEe8vViyU
09pi9lbK9ckP4bzqaXip5adVf6YU4FhFrqdPkqkCgYBGA1Ixcc2QLvdXI3XNH52E
1omTTnDFUp9NcId3JKyVhnte4wZaz/h9GHvnBfemBWWpziDauDeD1MgeeQ3S7pas
fB2XY8uWZRg9weofwWZERapRKok77tQPUZnaw5PWbQh89G2cwQyhrTS3tck4B7Y7
FcLW1foTZorEt3Pv5QzjQQKBgDuhi2SUvDlw919M47DxZXdoejuWVvc7XXdBsEIN
FbYA+SjFuebL2cdH6itY/Km/k+g0JxlFsSzo2jo6VUQ3FdpSpZq++VHH7574YxDM
eA8nF/+wQy8FrEQLOQjzc/jQOCUs+jf6jnw31XHTs2OsrfrN2BnQ4r7hK5aP8G7X
mSpJAoGBAL+483jZ4P2jphkPq13o//hqtqrgfRE9/ZXj313CQS3oJZoel4BbnZ3H
xIWe6ShjG2FMk15dCiAoF6fzksV9h6CSecwZSw7TxkJFkq0QjdW0leuQz/BF6NkM
6k00CYzxrPTCtfh7PJ5whNhQ2yN8sq1XNn0tWDX2OOFCPYVdQxbY
-----END RSA PRIVATE KEY-----


//2、生成CA证书请求文件

openssl req -new -out ca.csr -key ca.key -keyform PEM -subj "/C=CN/ST=江苏省/L=苏州市/O=单位/OU=部门/CN=域名或ip"

keyform和subj都是可选参数,只是提供更完善信息而已

.csr 是证书请求文件,是由 RFC 2986定义的PKCS10格式,包含部分/全部的请求证书的信息,比如,主题, 机构,国家等,并且包含了请求证书的公玥,这些被CA中心签名后返回一张证书。返回的证书是公钥证书(只包含公玥不含私钥)。

也就是说公司名称等这些参数是放在请求文件中的,并且含有公钥,一并交给CA机构,公钥怎么来的?是利用私钥生成的,因此这个步骤入参需要私钥

证书签名请求是申请人向证书颁发机构发送的一条消息,用于申请数字身份证书。

有 CSR 必定有 KEY,是成对的,CSR 最终变成为证书 crt,和私钥 key 配对使用。证书下发后,CSR 就没有用了,只是在交时候需要。

查看ca.csr:


[root@paas-controller-3:/home/ubuntu/test2]$ cat ca.csr
-----BEGIN CERTIFICATE REQUEST-----
MIIC2jCCAcICAQAwgZQxCzAJBgNVBAYTAkNOMRswGQYDVQQIDBLDpsKxwp/DqMKL
wo/Dp8KcwoExGzAZBgNVBAcMEsOowovCj8OlwrfCnsOlwrjCgjEVMBMGA1UECgwM
w6XCjcKVw6TCvcKNMRUwEwYDVQQLDAzDqcKDwqjDqcKXwqgxHTAbBgNVBAMMFMOl
wp/Cn8OlwpDCjcOmwojClmlwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEA2CYa3BH2Neb9fuA52lJQs336WLkM35oZCtOuVQcekxhVP/h1gryKI2ens5uq
xdlo1BX7IBDCi77D+kIS6LTuoyWO2d0zaowZFX9xzwd83CkJ8vPxaCCAfWgRvFzF
HjdR0aG+TnnkAID4VrrBqFMKeX079/hUQ4kl0pyn7BeB70dle80JDVl78IIp5JW5
HqzGrnf5rsX1kjgyWtRfCjk9AjZ7P0+TWQMqg2cNy7v8CWpKasUt/q+9PPq1eQQL
eOkc0s0B1iIisGZ4IxvTDtBMYyXjpygaXrORJcp1/rXSFExLoVcHMOTS0c5Zws7+
nn2RpVvXUyMKeMtgYo1y/LN+6QIDAQABoAAwDQYJKoZIhvcNAQELBQADggEBAKhm
nf7bICJvweHSomyUwVAA7855q6YEkWrO5SVtUPaNKtxKELR+EEe6QP5tIv5cJLm7
c3VmHX6YpQQWl9S6ac4PoKFqjMiUr0p4W1nX/wTUNBm6es3xmMrrYGvwus8FTxbr
3bn+O62iPC8B3yDAhErL5+u0SgDcyPJzqRdGw9zVLIm0jtO49Hrrpha28H6dt+fn
NNJ/GgTKL1MiLUzBSE4UJG9jxgQcY/o9ceE80Fa0ucERb0iYIKpxhTl1TxhMU7Rd
MdyfrJ6z/yjHiGuCR3iiwOMcgqrrcyf/1QJjQZr9Bxa+QizykXFwasXrPmKvKZyQ
OlEP8oPCBQX+SmBZL4U=
-----END CERTIFICATE REQUEST-----


//3、生成CA自签名 根证书

这一步是模拟CA公司执行的命令;之前的步骤私钥和请求文件都是客户自己生成的

openssl x509 -req -days 365 -signkey ca.key -in ca.csr -out ca.crt -CAcreateserial
$ openssl x509 -req -days 365 -signkey ca.key -in ca.csr -out ca.crt -CAcreateserial
Signature ok
subject=/C=CN/ST=\xC3\xA6\xC2\xB1\xC2\x9F\xC3\xA8\xC2\x8B\xC2\x8F\xC3\xA7\xC2\x9C\xC2\x81/L=\xC3\xA8\xC2\x8B\xC2\x8F\xC3\xA5\xC2\xB7\xC2\x9E\xC3\xA5\xC2\xB8\xC2\x82/O=\xC3\xA5\xC2\x8D\xC2\x95\xC3\xA4\xC2\xBD\xC2\x8D/OU=\xC3\xA9\xC2\x83\xC2\xA8\xC3\xA9\xC2\x97\xC2\xA8/CN=\xC3\xA5\xC2\x9F\xC2\x9F\xC3\xA5\xC2\x90\xC2\x8D\xC3\xA6\xC2\x88\xC2\x96ip
Getting Private key

生成了ca.crt ,查看ca.crt内容:

cat ca.crt
-----BEGIN CERTIFICATE-----
MIIDpjCCAo4CCQCj8QrD4K7XVTANBgkqhkiG9w0BAQsFADCBlDELMAkGA1UEBhMC
Q04xGzAZBgNVBAgMEsOmwrHCn8OowovCj8OnwpzCgTEbMBkGA1UEBwwSw6jCi8KP
w6XCt8Kew6XCuMKCMRUwEwYDVQQKDAzDpcKNwpXDpMK9wo0xFTATBgNVBAsMDMOp
woPCqMOpwpfCqDEdMBsGA1UEAwwUw6XCn8Kfw6XCkMKNw6bCiMKWaXAwHhcNMjMw
NTMxMDkxMTExWhcNMjQwNTMwMDkxMTExWjCBlDELMAkGA1UEBhMCQ04xGzAZBgNV
BAgMEsOmwrHCn8OowovCj8OnwpzCgTEbMBkGA1UEBwwSw6jCi8KPw6XCt8Kew6XC
uMKCMRUwEwYDVQQKDAzDpcKNwpXDpMK9wo0xFTATBgNVBAsMDMOpwoPCqMOpwpfC
qDEdMBsGA1UEAwwUw6XCn8Kfw6XCkMKNw6bCiMKWaXAwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQDYJhrcEfY15v1+4DnaUlCzffpYuQzfmhkK065VBx6T
GFU/+HWCvIojZ6ezm6rF2WjUFfsgEMKLvsP6QhLotO6jJY7Z3TNqjBkVf3HPB3zc
KQny8/FoIIB9aBG8XMUeN1HRob5OeeQAgPhWusGoUwp5fTv3+FRDiSXSnKfsF4Hv
R2V7zQkNWXvwginklbkerMaud/muxfWSODJa1F8KOT0CNns/T5NZAyqDZw3Lu/wJ
akpqxS3+r708+rV5BAt46RzSzQHWIiKwZngjG9MO0ExjJeOnKBpes5ElynX+tdIU
TEuhVwcw5NLRzlnCzv6efZGlW9dTIwp4y2BijXL8s37pAgMBAAEwDQYJKoZIhvcN
AQELBQADggEBAJG+uTTMBG3bv/LnNG7ycaalVX0GdKXTAoCyT1pYdFMcjnLmpf7i
Zj3TVr1PAWGxxewEh52k+OHctfFMxHAb4oiivtAoX9Dd5+K8Nkh0EcawEGhXQpZb
YldK/PV3Mgurg1sW323UHSvOgWCMC78L3l47yaU8gNGv9lJNMsnF6AdLylj2ds3z
detapoewhsSKkbU7Zva2BeMp6R7Gb6VQgYFAMkjP3DUp3R5gLV7R/K+rp2iVOCIO
OFkTGYe3AA50FzI44JIbxzpQWXpwLYeUBpJ0/nJEZVmdOSkGrMsktTpepuoBEWqZ
+2k4jklswJ3pTbgtRI9Kl/+LxWwHmAYzEZU=
-----END CERTIFICATE-----


//4、生成server端秘钥

openssl genrsa  -out server.key 2048    

生成了server.key

]$ cat server.key
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAqBPoLU/5WoPJtt/s4HLO7cVrihGO3s9gpPtz9VVrET3Sj+Wk
xCOgeKngv1BZrT+11UaYwH9Jjf2zTp67ZKb2HOdVXVUy6R9qSK8+2TxtQUp35h2/
o5cf5/dstymf1Bl/2TkNLn/hdY+Qo4ArSqgUhbUwVCEZL7M9jlWBSWkxRKxNcy7a
XOSlZyXjMUbHx46ErvWbwqVCjYIGNdqmtouDrSVfECKBPeG2PrpioGW942tpq0yk
SIi4KATWf0sPhXul10exXu27i7KA+ocfZu6dE5yC4Wmi2VDo76Y4PtHRva6WZCMv
TRJM11ztZaDzqdc4r/9XrxHF/W6CO8y9mJDf3wIDAQABAoIBAG8O+FM4jOMqQZb8
z2BffCvQTwakI2tGS+232R86mcyCtScv7ndLszUHyuGfDiJT/qo2Q6iucsPH5zsD
137ic60VjmplaYZwo6HzaevQ6cBCnIcJER/fM83qx4MfleRoFPpLoFIhXbB4dHIU
toZWGXlgB9cPJ71FCl+KUCtZvpxIyvS1BbPWPLV5qi6fUxAg2yqFW3Mr6LNhytOw
ATv6ghg7jrDOxEZB/rhZcmiL+KIFHPVU83W8dmH9QS9gVZytY22awixaMLB2OMxu
01V7yPdbWrUTPuX8xstfKbOQ9iB4QfXayqz2wtgEV8W7K+zXaf5k6GWHM89A0sYv
9TG3PIECgYEA3ppgSuKr/4HGV9ajNRn8SrPAUtKi25diyWhUQ1ZVJTwV7uWOfNxB
oh3NhnB7EyQ2rdx6+UiHO5DjSpAvPG8rT0Gf9b8HhDvsqB2xScTTJZoaM9Afdsvd
ZQFSrDIFF2n7jZgH6SBtQB/Be2WxVivypQP//30pbdoa/vHyye+rOBcCgYEAwUta
HAdehuWSbypX5LAyS7JHRLmsQftndyF0Sv8Ag1B9KmHtOuGQiXM3DCGMi7v0wGGD
J+8HIzb2NPso2RxxuhKRdX5XpLu0Ao9SyRMw/pLhTzT2D4b5U+1YY2igyDkJDAY/
4E4285Bz9NlHnmPossG2MEPJdCUYkrZHgs60q3kCgYAIdt5KeqwHnyunk2XJUx+g
x4z8mT3QE8WR2wG5PcMnE03SM7BjVwy32WJDRmunoqzhl4ylhfh+b1f1Md5Z8fA3
p0sp0QW8JXsuOVLQd0eAGof8iGFp5v6YJKC8I3rGFSWXkLxcRPtigNKempNPr4Qe
ejR1xpCYuL5mC1UsEIz2KQKBgFrbJWbpW9hCjpssJxY6b9m+2dsG/14gYtjPY89g
n4gZzEugrhawMfU5r9VG674+weOvsiuSIiO+UOpEaEXtJdPVqIO2uFGZXRqa7cnP
+Iag2cEWXtablhSKCrLnWjPjA0qgoWO4wAGqk6ayfwSHZ7imbxGuu0GZsjw7688j
hC7ZAoGAOnPh68KireDKK85Z4+AhEO1Fh6RdgBs02erN+MmbNLXMpAqXyJaa0lmW
5Xt0VOuGGFofCKkrgLWgXe78ZFdcjE+mB9e7ogmVLh5JTv2oXsVLC4bndrQEmZKg
4gpWtdm+RtoK9DIsiphwbiRIaJ5pfSD0v7Sc6J3FPqEQjua2Ox0=
-----END RSA PRIVATE KEY-----

//5、生成server证书请求文件

openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=江苏省/L=常州市/O=单位/OU=部门/CN=域名或ip"

生成了server.csr

$ cat server.csr
-----BEGIN CERTIFICATE REQUEST-----
MIIC2jCCAcICAQAwgZQxCzAJBgNVBAYTAkNOMRswGQYDVQQIDBLDpsKxwp/DqMKL
wo/Dp8KcwoExGzAZBgNVBAcMEsOlwrjCuMOlwrfCnsOlwrjCgjEVMBMGA1UECgwM
w6XCjcKVw6TCvcKNMRUwEwYDVQQLDAzDqcKDwqjDqcKXwqgxHTAbBgNVBAMMFMOl
wp/Cn8OlwpDCjcOmwojClmlwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEAqBPoLU/5WoPJtt/s4HLO7cVrihGO3s9gpPtz9VVrET3Sj+WkxCOgeKngv1BZ
rT+11UaYwH9Jjf2zTp67ZKb2HOdVXVUy6R9qSK8+2TxtQUp35h2/o5cf5/dstymf
1Bl/2TkNLn/hdY+Qo4ArSqgUhbUwVCEZL7M9jlWBSWkxRKxNcy7aXOSlZyXjMUbH
x46ErvWbwqVCjYIGNdqmtouDrSVfECKBPeG2PrpioGW942tpq0ykSIi4KATWf0sP
hXul10exXu27i7KA+ocfZu6dE5yC4Wmi2VDo76Y4PtHRva6WZCMvTRJM11ztZaDz
qdc4r/9XrxHF/W6CO8y9mJDf3wIDAQABoAAwDQYJKoZIhvcNAQELBQADggEBAESP
6I+f/UiWkdtwbdfpZnteCtzd6y3lqkorjXl205SV0sGxFxnxwNqPP8qGA6jhDgnc
SAEYmYqTQwMpK0f+XCHQ5Tx/OSx8glDkFWz7RNPeVMbcpQgTJyuwr2dV2x2lxqDa
v9UqfkXBBVb8BHBj4YJm7uAiBzGIze+A3byIMnq8KnRRmdA8dgzvRnXknJg7QQid
hBSNYpMLUA8qDyqWru/7b+D9Ze5rSFc6FL3HzaAeuJMQHxO2Mk6Q4qDplgtBPkXx
/XapyYvjatTBMBtRaBlk49XpqPh7K58nmWG6nes7wGhPn/6LQCp00A9Cgqp6R5y0
6tqPT92LjQyQte2AAYY=
-----END CERTIFICATE REQUEST-----

//6、生成自签名SSL证书

这次和以上不一样,加上了一个中间人 CA ,表示这是由 CA 认可并颁发的证书

openssl x509 -req -in server.csr -out server.crt  -CA ca.crt -CAkey ca.key -days 365 -CAcreateserial

生成了server.crt

注意:生成了证书,证书内含有公钥,因此,不需要单独提供公钥

$ cat ca.crt
-----BEGIN CERTIFICATE-----
MIIDpjCCAo4CCQCj8QrD4K7XVTANBgkqhkiG9w0BAQsFADCBlDELMAkGA1UEBhMC
Q04xGzAZBgNVBAgMEsOmwrHCn8OowovCj8OnwpzCgTEbMBkGA1UEBwwSw6jCi8KP
w6XCt8Kew6XCuMKCMRUwEwYDVQQKDAzDpcKNwpXDpMK9wo0xFTATBgNVBAsMDMOp
woPCqMOpwpfCqDEdMBsGA1UEAwwUw6XCn8Kfw6XCkMKNw6bCiMKWaXAwHhcNMjMw
NTMxMDkxMTExWhcNMjQwNTMwMDkxMTExWjCBlDELMAkGA1UEBhMCQ04xGzAZBgNV
BAgMEsOmwrHCn8OowovCj8OnwpzCgTEbMBkGA1UEBwwSw6jCi8KPw6XCt8Kew6XC
uMKCMRUwEwYDVQQKDAzDpcKNwpXDpMK9wo0xFTATBgNVBAsMDMOpwoPCqMOpwpfC
qDEdMBsGA1UEAwwUw6XCn8Kfw6XCkMKNw6bCiMKWaXAwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQDYJhrcEfY15v1+4DnaUlCzffpYuQzfmhkK065VBx6T
GFU/+HWCvIojZ6ezm6rF2WjUFfsgEMKLvsP6QhLotO6jJY7Z3TNqjBkVf3HPB3zc
KQny8/FoIIB9aBG8XMUeN1HRob5OeeQAgPhWusGoUwp5fTv3+FRDiSXSnKfsF4Hv
R2V7zQkNWXvwginklbkerMaud/muxfWSODJa1F8KOT0CNns/T5NZAyqDZw3Lu/wJ
akpqxS3+r708+rV5BAt46RzSzQHWIiKwZngjG9MO0ExjJeOnKBpes5ElynX+tdIU
TEuhVwcw5NLRzlnCzv6efZGlW9dTIwp4y2BijXL8s37pAgMBAAEwDQYJKoZIhvcN
AQELBQADggEBAJG+uTTMBG3bv/LnNG7ycaalVX0GdKXTAoCyT1pYdFMcjnLmpf7i
Zj3TVr1PAWGxxewEh52k+OHctfFMxHAb4oiivtAoX9Dd5+K8Nkh0EcawEGhXQpZb
YldK/PV3Mgurg1sW323UHSvOgWCMC78L3l47yaU8gNGv9lJNMsnF6AdLylj2ds3z
detapoewhsSKkbU7Zva2BeMp6R7Gb6VQgYFAMkjP3DUp3R5gLV7R/K+rp2iVOCIO
OFkTGYe3AA50FzI44JIbxzpQWXpwLYeUBpJ0/nJEZVmdOSkGrMsktTpepuoBEWqZ
+2k4jklswJ3pTbgtRI9Kl/+LxWwHmAYzEZU=
-----END CERTIFICATE-----

//7、生成client证书,与生成server证书过程一样,重复4-6步
分别生成 客户端密钥 client.key、客户端请求文件client.csr、客户端证书 client.crt

总结:请求文件是中间临时文件,不会在代码应用中体现,而密钥和证书都会在代码中体现

4. 查看密钥

4.1 用openssl命令查看私钥的明细

$ openssl rsa -in server.key -noout -text
Private-Key: (2048 bit)
modulus:
    00:a8:13:e8:2d:4f:f9:5a:83:c9:b6:df:ec:e0:72:      //这个是公钥,也就是说生成的私钥同时也会产生公钥
    ce:ed:c5:6b:8a:11:8e:de:cf:60:a4:fb:73:f5:55:
    6b:11:3d:d2:8f:e5:a4:c4:23:a0:78:a9:e0:bf:50:
    59:ad:3f:b5:d5:46:98:c0:7f:49:8d:fd:b3:4e:9e:
    bb:64:a6:f6:1c:e7:55:5d:55:32:e9:1f:6a:48:af:
    3e:d9:3c:6d:41:4a:77:e6:1d:bf:a3:97:1f:e7:f7:
    6c:b7:29:9f:d4:19:7f:d9:39:0d:2e:7f:e1:75:8f:
    90:a3:80:2b:4a:a8:14:85:b5:30:54:21:19:2f:b3:
    3d:8e:55:81:49:69:31:44:ac:4d:73:2e:da:5c:e4:
    a5:67:25:e3:31:46:c7:c7:8e:84:ae:f5:9b:c2:a5:
    42:8d:82:06:35:da:a6:b6:8b:83:ad:25:5f:10:22:
    81:3d:e1:b6:3e:ba:62:a0:65:bd:e3:6b:69:ab:4c:
    a4:48:88:b8:28:04:d6:7f:4b:0f:85:7b:a5:d7:47:
    b1:5e:ed:bb:8b:b2:80:fa:87:1f:66:ee:9d:13:9c:
    82:e1:69:a2:d9:50:e8:ef:a6:38:3e:d1:d1:bd:ae:
    96:64:23:2f:4d:12:4c:d7:5c:ed:65:a0:f3:a9:d7:
    38:af:ff:57:af:11:c5:fd:6e:82:3b:cc:bd:98:90:
    df:df
publicExponent: 65537 (0x10001)
privateExponent:
    6f:0e:f8:53:38:8c:e3:2a:41:96:fc:cf:60:5f:7c:
    2b:d0:4f:06:a4:23:6b:46:4b:ed:b7:d9:1f:3a:99:
    cc:82:b5:27:2f:ee:77:4b:b3:35:07:ca:e1:9f:0e:
    22:53:fe:aa:36:43:a8:ae:72:c3:c7:e7:3b:03:d7:
    7e:e2:73:ad:15:8e:6a:65:69:86:70:a3:a1:f3:69:
    eb:d0:e9:c0:42:9c:87:09:11:1f:df:33:cd:ea:c7:
    83:1f:95:e4:68:14:fa:4b:a0:52:21:5d:b0:78:74:
    72:14:b6:86:56:19:79:60:07:d7:0f:27:bd:45:0a:
    5f:8a:50:2b:59:be:9c:48:ca:f4:b5:05:b3:d6:3c:
    b5:79:aa:2e:9f:53:10:20:db:2a:85:5b:73:2b:e8:
    b3:61:ca:d3:b0:01:3b:fa:82:18:3b:8e:b0:ce:c4:
    46:41:fe:b8:59:72:68:8b:f8:a2:05:1c:f5:54:f3:
    75:bc:76:61:fd:41:2f:60:55:9c:ad:63:6d:9a:c2:
    2c:5a:30:b0:76:38:cc:6e:d3:55:7b:c8:f7:5b:5a:
    b5:13:3e:e5:fc:c6:cb:5f:29:b3:90:f6:20:78:41:
    f5:da:ca:ac:f6:c2:d8:04:57:c5:bb:2b:ec:d7:69:
    fe:64:e8:65:87:33:cf:40:d2:c6:2f:f5:31:b7:3c:
    81
prime1:
    00:de:9a:60:4a:e2:ab:ff:81:c6:57:d6:a3:35:19:
    fc:4a:b3:c0:52:d2:a2:db:97:62:c9:68:54:43:56:
    55:25:3c:15:ee:e5:8e:7c:dc:41:a2:1d:cd:86:70:
    7b:13:24:36:ad:dc:7a:f9:48:87:3b:90:e3:4a:90:
    2f:3c:6f:2b:4f:41:9f:f5:bf:07:84:3b:ec:a8:1d:
    b1:49:c4:d3:25:9a:1a:33:d0:1f:76:cb:dd:65:01:
    52:ac:32:05:17:69:fb:8d:98:07:e9:20:6d:40:1f:
    c1:7b:65:b1:56:2b:f2:a5:03:ff:ff:7d:29:6d:da:
    1a:fe:f1:f2:c9:ef:ab:38:17
prime2:
    00:c1:4b:5a:1c:07:5e:86:e5:92:6f:2a:57:e4:b0:
    32:4b:b2:47:44:b9:ac:41:fb:67:77:21:74:4a:ff:
    00:83:50:7d:2a:61:ed:3a:e1:90:89:73:37:0c:21:
    8c:8b:bb:f4:c0:61:83:27:ef:07:23:36:f6:34:fb:
    28:d9:1c:71:ba:12:91:75:7e:57:a4:bb:b4:02:8f:
    52:c9:13:30:fe:92:e1:4f:34:f6:0f:86:f9:53:ed:
    58:63:68:a0:c8:39:09:0c:06:3f:e0:4e:36:f3:90:
    73:f4:d9:47:9e:63:e8:b2:c1:b6:30:43:c9:74:25:
    18:92:b6:47:82:ce:b4:ab:79
exponent1:
    08:76:de:4a:7a:ac:07:9f:2b:a7:93:65:c9:53:1f:
    a0:c7:8c:fc:99:3d:d0:13:c5:91:db:01:b9:3d:c3:
    27:13:4d:d2:33:b0:63:57:0c:b7:d9:62:43:46:6b:
    a7:a2:ac:e1:97:8c:a5:85:f8:7e:6f:57:f5:31:de:
    59:f1:f0:37:a7:4b:29:d1:05:bc:25:7b:2e:39:52:
    d0:77:47:80:1a:87:fc:88:61:69:e6:fe:98:24:a0:
    bc:23:7a:c6:15:25:97:90:bc:5c:44:fb:62:80:d2:
    9e:9a:93:4f:af:84:1e:7a:34:75:c6:90:98:b8:be:
    66:0b:55:2c:10:8c:f6:29
exponent2:
    5a:db:25:66:e9:5b:d8:42:8e:9b:2c:27:16:3a:6f:
    d9:be:d9:db:06:ff:5e:20:62:d8:cf:63:cf:60:9f:
    88:19:cc:4b:a0:ae:16:b0:31:f5:39:af:d5:46:eb:
    be:3e:c1:e3:af:b2:2b:92:22:23:be:50:ea:44:68:
    45:ed:25:d3:d5:a8:83:b6:b8:51:99:5d:1a:9a:ed:
    c9:cf:f8:86:a0:d9:c1:16:5e:d6:9b:96:14:8a:0a:
    b2:e7:5a:33:e3:03:4a:a0:a1:63:b8:c0:01:aa:93:
    a6:b2:7f:04:87:67:b8:a6:6f:11:ae:bb:41:99:b2:
    3c:3b:eb:cf:23:84:2e:d9
coefficient:
    3a:73:e1:eb:c2:a2:ad:e0:ca:2b:ce:59:e3:e0:21:
    10:ed:45:87:a4:5d:80:1b:34:d9:ea:cd:f8:c9:9b:
    34:b5:cc:a4:0a:97:c8:96:9a:d2:59:96:e5:7b:74:
    54:eb:86:18:5a:1f:08:a9:2b:80:b5:a0:5d:ee:fc:
    64:57:5c:8c:4f:a6:07:d7:bb:a2:09:95:2e:1e:49:
    4e:fd:a8:5e:c5:4b:0b:86:e7:76:b4:04:99:92:a0:
    e2:0a:56:b5:d9:be:46:da:0a:f4:32:2c:8a:98:70:
    6e:24:48:68:9e:69:7d:20:f4:bf:b4:9c:e8:9d:c5:
    3e:a1:10:8e:e6:b6:3b:1d

4.2 由私钥生成对应的公钥

确切的来说,是从私钥中导出公钥,因为私钥和公钥是一对,二者同时生成,并集成在私钥中!

openssl rsa -in server.key -pubout -out publickey.key

$ cat publickey.key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqBPoLU/5WoPJtt/s4HLO
7cVrihGO3s9gpPtz9VVrET3Sj+WkxCOgeKngv1BZrT+11UaYwH9Jjf2zTp67ZKb2
HOdVXVUy6R9qSK8+2TxtQUp35h2/o5cf5/dstymf1Bl/2TkNLn/hdY+Qo4ArSqgU
hbUwVCEZL7M9jlWBSWkxRKxNcy7aXOSlZyXjMUbHx46ErvWbwqVCjYIGNdqmtouD
rSVfECKBPeG2PrpioGW942tpq0ykSIi4KATWf0sPhXul10exXu27i7KA+ocfZu6d
E5yC4Wmi2VDo76Y4PtHRva6WZCMvTRJM11ztZaDzqdc4r/9XrxHF/W6CO8y9mJDf
3wIDAQAB
-----END PUBLIC KEY-----

查看公钥详细:

$ openssl rsa -pubin -in publickey.key -noout -text    
Public-Key: (2048 bit)
Modulus:
    00:a8:13:e8:2d:4f:f9:5a:83:c9:b6:df:ec:e0:72:
    ce:ed:c5:6b:8a:11:8e:de:cf:60:a4:fb:73:f5:55:
    6b:11:3d:d2:8f:e5:a4:c4:23:a0:78:a9:e0:bf:50:
    59:ad:3f:b5:d5:46:98:c0:7f:49:8d:fd:b3:4e:9e:
    bb:64:a6:f6:1c:e7:55:5d:55:32:e9:1f:6a:48:af:
    3e:d9:3c:6d:41:4a:77:e6:1d:bf:a3:97:1f:e7:f7:
    6c:b7:29:9f:d4:19:7f:d9:39:0d:2e:7f:e1:75:8f:
    90:a3:80:2b:4a:a8:14:85:b5:30:54:21:19:2f:b3:
    3d:8e:55:81:49:69:31:44:ac:4d:73:2e:da:5c:e4:
    a5:67:25:e3:31:46:c7:c7:8e:84:ae:f5:9b:c2:a5:
    42:8d:82:06:35:da:a6:b6:8b:83:ad:25:5f:10:22:
    81:3d:e1:b6:3e:ba:62:a0:65:bd:e3:6b:69:ab:4c:
    a4:48:88:b8:28:04:d6:7f:4b:0f:85:7b:a5:d7:47:
    b1:5e:ed:bb:8b:b2:80:fa:87:1f:66:ee:9d:13:9c:
    82:e1:69:a2:d9:50:e8:ef:a6:38:3e:d1:d1:bd:ae:
    96:64:23:2f:4d:12:4c:d7:5c:ed:65:a0:f3:a9:d7:
    38:af:ff:57:af:11:c5:fd:6e:82:3b:cc:bd:98:90:
    df:df
Exponent: 65537 (0x10001)

与查看公钥的详细命令区别:多了一个-pubin,表明是公钥,默认是私钥

5. 查看证书

有关证书的详细的命令 openssl x509 --help

-noout 作用是排除不想的信息,默认会打印指定信息后,会额外打印全部信息

5.1 查看完整的证书

openssl x509 -noout -text -in server.crt

$ openssl x509 -noout -text -in server.crt
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            f9:4d:84:06:6e:44:c3:a7
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=CN, ST=\xC3\xA6\xC2\xB1\xC2\x9F\xC3\xA8\xC2\x8B\xC2\x8F\xC3\xA7\xC2\x9C\xC2\x81, L=\xC3\xA8\xC2\x8B\xC2\x8F\xC3\xA5\xC2\xB7\xC2\x9E\xC3\xA5\xC2\xB8\xC2\x82, O=\xC3\xA5\xC2\x8D\xC2\x95\xC3\xA4\xC2\xBD\xC2\x8D, OU=\xC3\xA9\xC2\x83\xC2\xA8\xC3\xA9\xC2\x97\xC2\xA8, CN=\xC3\xA5\xC2\x9F\xC2\x9F\xC3\xA5\xC2\x90\xC2\x8D\xC3\xA6\xC2\x88\xC2\x96ip
        Validity
            Not Before: May 31 09:20:56 2023 GMT
            Not After : May 30 09:20:56 2024 GMT
        Subject: C=CN, ST=\xC3\xA6\xC2\xB1\xC2\x9F\xC3\xA8\xC2\x8B\xC2\x8F\xC3\xA7\xC2\x9C\xC2\x81, L=\xC3\xA5\xC2\xB8\xC2\xB8\xC3\xA5\xC2\xB7\xC2\x9E\xC3\xA5\xC2\xB8\xC2\x82, O=\xC3\xA5\xC2\x8D\xC2\x95\xC3\xA4\xC2\xBD\xC2\x8D, OU=\xC3\xA9\xC2\x83\xC2\xA8\xC3\xA9\xC2\x97\xC2\xA8, CN=\xC3\xA5\xC2\x9F\xC2\x9F\xC3\xA5\xC2\x90\xC2\x8D\xC3\xA6\xC2\x88\xC2\x96ip
        Subject Public Key Info:     //公钥信息16进制形式,对应openssl x509 -in server.crt -noout -pubkey
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit) 
                    Modulus:
                    00:a8:13:e8:2d:4f:f9:5a:83:c9:b6:df:ec:e0:72:   //公钥信息和《4.2 由私钥生产对应的公钥》内容是一样的
                    ce:ed:c5:6b:8a:11:8e:de:cf:60:a4:fb:73:f5:55:
                    6b:11:3d:d2:8f:e5:a4:c4:23:a0:78:a9:e0:bf:50:
                    59:ad:3f:b5:d5:46:98:c0:7f:49:8d:fd:b3:4e:9e:
                    bb:64:a6:f6:1c:e7:55:5d:55:32:e9:1f:6a:48:af:
                    3e:d9:3c:6d:41:4a:77:e6:1d:bf:a3:97:1f:e7:f7:
                    6c:b7:29:9f:d4:19:7f:d9:39:0d:2e:7f:e1:75:8f:
                    90:a3:80:2b:4a:a8:14:85:b5:30:54:21:19:2f:b3:
                    3d:8e:55:81:49:69:31:44:ac:4d:73:2e:da:5c:e4:
                    a5:67:25:e3:31:46:c7:c7:8e:84:ae:f5:9b:c2:a5:
                    42:8d:82:06:35:da:a6:b6:8b:83:ad:25:5f:10:22:
                    81:3d:e1:b6:3e:ba:62:a0:65:bd:e3:6b:69:ab:4c:
                    a4:48:88:b8:28:04:d6:7f:4b:0f:85:7b:a5:d7:47:
                    b1:5e:ed:bb:8b:b2:80:fa:87:1f:66:ee:9d:13:9c:
                    82:e1:69:a2:d9:50:e8:ef:a6:38:3e:d1:d1:bd:ae:
                    96:64:23:2f:4d:12:4c:d7:5c:ed:65:a0:f3:a9:d7:
                    38:af:ff:57:af:11:c5:fd:6e:82:3b:cc:bd:98:90:
                    df:df
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
         23:d4:ba:1a:f8:1e:25:f1:b7:42:48:a3:3e:d6:dc:78:f6:e4:
         67:73:b8:59:bf:a0:6a:5f:21:fa:a3:a7:0e:6c:fd:e2:04:78:
         c5:9b:5b:89:b9:a2:fb:14:78:af:25:9a:5c:5a:73:d4:b3:fc:
         38:5c:c6:44:0a:3f:78:fe:09:84:09:d2:66:95:d7:b3:97:ca:
         43:9f:20:e2:36:59:9f:77:5e:23:64:8d:ee:13:96:a9:a0:a0:
         51:2c:03:1a:03:d3:04:1d:0c:fd:60:0a:f6:cb:c5:30:04:3b:
         54:c2:03:46:e3:f3:0a:55:01:38:8f:01:5d:78:08:a5:d6:56:
         41:05:2f:4d:cc:59:18:e4:c5:5b:6b:d5:e6:dc:32:2b:4d:14:
         a1:b2:0c:93:ad:74:2e:4d:46:b9:96:6b:da:60:12:c0:82:64:
         b1:7a:ed:86:40:34:49:8b:1f:fb:b1:9f:01:ca:b9:5c:74:64:
         00:d1:5a:58:a0:6c:1d:5e:4e:60:c5:49:d4:d8:58:3c:b3:28:
         49:6d:28:db:38:fc:62:f9:05:a8:1d:11:0e:e9:f8:cb:95:2d:
         76:fc:26:28:4a:07:8f:c5:47:04:cc:a7:ca:94:00:64:3d:4c:
         fb:f7:e2:f1:30:91:2d:57:c2:a6:7c:c6:80:6b:26:ba:ef:53:
         0c:7d:e2:ed


证书中的公钥信息和《4.2 由私钥生产对应的公钥》内容是一样的,即生成私钥的同时会生成公钥,并把公钥存在私钥中,在生成证书请求文件时,会把公钥存在该请求文件,签发机构签发的证书中,会包含请求文件中的公钥!

5.2 查看证书序列号

openssl x509 -in server.crt -noout -serial

serial=E92BA025ED18CAD2

5.3 查看公钥

可以从证书中查看公钥信息

openssl x509 -in server.crt -noout -pubkey

$  openssl x509 -in server.crt -noout -pubkey
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqBPoLU/5WoPJtt/s4HLO
7cVrihGO3s9gpPtz9VVrET3Sj+WkxCOgeKngv1BZrT+11UaYwH9Jjf2zTp67ZKb2
HOdVXVUy6R9qSK8+2TxtQUp35h2/o5cf5/dstymf1Bl/2TkNLn/hdY+Qo4ArSqgU
hbUwVCEZL7M9jlWBSWkxRKxNcy7aXOSlZyXjMUbHx46ErvWbwqVCjYIGNdqmtouD
rSVfECKBPeG2PrpioGW942tpq0ykSIi4KATWf0sPhXul10exXu27i7KA+ocfZu6d
E5yC4Wmi2VDo76Y4PtHRva6WZCMvTRJM11ztZaDzqdc4r/9XrxHF/W6CO8y9mJDf
3wIDAQAB
-----END PUBLIC KEY-----

5.4 查看证书有效期

openssl x509 -enddate -in server.crt -noout
notAfter=May 30 09:20:56 2024 GMT

6. 使用公钥对明文进行加密/解密

使用公钥对明文进行加密

$ echo "hello" >> hello.txt             //原始文本hello.txt
$ cat hello.txt
hello
$ openssl rsautl -encrypt -pubin -inkey  publickey.key -in hello.txt -out hello_encoded.txt    //加密后文本hello_encoded.txt    

密文结果如下:

$ cat hello_encoded.txt
{▒99q▒rA▒\▒▒▒▒R▒X▒▒?▒Y5ּM'▒▒V▒▒J5\▒▒5▒<▒▒▒▒▒^▒I▒ ▒
▒▒?v_e▒▒▒$}▒"▒|▒▒▒p▒<▒AK▒▒▒S▒QL\MIƱ▒<▒▒)/lP;h;Q▒▒▒!▒▒eaqFa+▒▒▒'=▒);'▒O▒S▒}▒▒)▒[S▒▒▒▒▒▒▒▒▒s▒R▒▒y▒\6l;{▒M▒
e▒ߊ▒

解密,使用私钥解密

$ openssl rsautl -decrypt -inkey server.key -in hello_encoded.txt
hello

7 利用CA校验证书

单向验证server证书:
openssl verify -CAfile ca.crt server.crt

$ openssl verify -CAfile ca.crt server.crt
server.crt: OK

单向验证client证书
openssl verify -CAfile ca.crt client.crt

$  openssl verify -CAfile ca.crt client.crt
client.crt: OK

三、WebSocket基于TLS/SSL双向认证通信(Python示例)

网上有一些http和https的SSL双向认证示例,没有挨个尝试,可自行搜索引擎。这里写一个Websocket的示例,仅供分享。

Python环境:3.6.6
依赖模块:websockets
这里引用了部分Websockets example中的示例代码,感谢!

server.py(server端代码)

#!/usr/bin/env python

import asyncio
import pathlib
import ssl
import websockets

async def hello(websocket, path):
    name = await websocket.recv()
    print(f"< {name}")

    greeting = f"Hello {name}!"

    await websocket.send(greeting)
    print(f"> {greeting}")
//服务端声明CLIENT_AUTH
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
//certfile和keyfile参数为,证书及文件的路径
ssl_context.load_cert_chain(certfile="cert/server.crt",keyfile="cert/server.key")
//load_verify_locations加载客户端证书
ssl_context.load_verify_locations("cert/client.crt")
ssl_context.verify_mode=ssl.CERT_REQUIRED


start_server = websockets.serve(
    hello, "localhost", 1234, ssl=ssl_context
)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

client.py(client端代码)

#!/usr/bin/env python

import asyncio
import pathlib
import ssl
import websockets

//服务端声明SERVER_AUTH,并加载server端证书
ssl_context=ssl.create_default_context(ssl.Purpose.SERVER_AUTH,cafile="cert/server.crt")
ssl_context.check_hostname=False
//certfile和keyfile参数为,证书及文件的路径
ssl_context.load_cert_chain(certfile="cert/client.crt",keyfile="cert/client.key")
ssl_context.verify_mode=ssl.CERT_REQUIRED

async def hello():
    uri = "wss://localhost:1234"
    async with websockets.connect(
        uri, ssl=ssl_context
    ) as websocket:
        name = input("What's your name? ")

        await websocket.send(name)
        print(f"> {name}")

        greeting = await websocket.recv()
        print(f"< {greeting}")

asyncio.get_event_loop().run_until_complete(hello())

参考

手把手实现TLS/SSL双向认证(附Websocket实现代码)
openssl x509参数介绍(官方完整版)
OpenSSL生成CA自签名根证书和颁发证书
openssl私有CA证书签发与单双向认证 ca证书校验 其签发的证书
openssl校验证书 校验证书和私钥是否匹配,本质是检查证书的公钥和私钥中的公钥Md5值是否相同

本文标签: 证书示例双向概念内容