一、SSL认证原理
1.SSL单向认证
对于SSL单向认证:
服务器需要CA证书、server证书、server私钥,客户端需要CA证书。
认证原理:
SSL证书单向认证主要是客户端对服务器身份的验证。当客户端向服务器发起连接请求时,服务器会将自己的数字证书发送给客户端。该数字证书包含了服务器的公钥、证书颁发机构(CA)的签名、证书有效期等信息。客户端会使用预先安装在系统中的CA根证书来验证服务器证书的合法性。如果验证通过,客户端就会认为服务器的身份是可信的,然后双方开始协商加密密钥,建立安全的通信通道。
2.SSL双向认证
对于SSL双向认证:
服务器需要CA证书、server证书、server私钥,客户端需要CA证书,client证书、client私钥。
认证原理:
SSL证书双向认证不仅要求客户端验证服务器的身份,同时也要求服务器验证客户端的身份。在单向认证的基础上,增加了服务器对客户端证书的验证环节。客户端和服务器都需要拥有自己的数字证书,并且都要通过对方的证书验证。
CA证书是证书颁发机构,server证书是颁发对象
二、生成CA证书
1.生成私钥(Private Key)
openssl genrsa -out ca.key 2048
2.生成证书签名请求(CSR)
openssl req -new -key ca.key -out ca.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=MyCompany/OU=Dev/CN=Ca/emailAddress=admin@test.com"
验证签名请求信息
openssl req -in ca.csr -text -noout
3.生成自签名证书(Self-Signed Certificate)
openssl x509 -req -days 3650 -extensions v3_ca -extfile /etc/ssl/openssl.cnf -signkey ca.key -in ca.csr -out ca.crt
验证证书信息
openssl x509 -in ca.crt -text -noout
三、生成服务器证书
1.生成私钥(Private Key)
openssl genrsa -out server.key 2048
2.生成证书签名请求(CSR)
CSR(Certificate Signing Request)是包含公钥及主体信息的证书请求文件。即便是自签名证书,也推荐通过 CSR 来规范生成证书的过程。
证数各参数含义如下:
C-----国家(Country Name)
ST----省份(State or Province Name)
L----城市(Locality Name)
O----公司(Organization Name)
OU----部门(Organizational Unit Name)
CN----产品名(Common Name)
emailAddress----邮箱(Email Address)
根证书的 Common Name 可以填写 root 或者个人、单位信息
服务器端证书的 Common Name 可以填写域名或者IP或者单位
客户端证书的 Common Name 可以填写个人信息
方式一,生成不带 SAN 的 csr:
openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=MyCompany/OU=Dev/CN=www.test.com/emailAddress=admin@test.com"
如果生成不带 SAN 的 csr,其中 Common Name(CN) 非常重要,一般与访问域名一致。
方式二,生成带 SAN 的 csr:
server.cnf
[ req ]
default_bits = 2048
default_md = sha256
distinguished_name = req_distinguished_name
req_extensions = req_ext
prompt = no
[ req_distinguished_name ]
C = CN
ST = Zhejiang
L = Hangzhou
O = MyCompany
OU = Dev
CN = Server
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = test.com
DNS.2 = www.test.com
DNS.3 = api.test.com
IP.1 = 127.0.0.1
openssl req -new -key server.key -out server.csr -config server.cnf
验证签名请求信息
openssl req -in server.csr -text -noout
3.生成CA证书签署服务器证书
方式一,如果不带 SAN 的 csr,则生成 crt:
openssl x509 -req -days 3650 -extensions v3_req -extfile /etc/ssl/openssl.cnf -CA ca.crt -CAkey ca.key -CAserial ca.srl -CAcreateserial -in server.csr -out server.crt
方式二,如果带 SAN 的 csr,则生成 crt:
创建一个扩展配置文件 v3.ext
basicConstraints=CA:FALSE
subjectAltName=@alt_names
keyUsage=digitalSignature, keyEncipherment
extendedKeyUsage=serverAuth
[alt_names]
DNS.1 = test.com
DNS.2 = www.test.com
DNS.3 = api.test.com
IP.1 = 127.0.0.1
openssl x509 -req -days 3650 -extfile v3.ext -CA ca.crt -CAkey ca.key -CAserial ca.srl -CAcreateserial -in server.csr -out server.crt
验证证书信息
openssl x509 -in server.crt -text -noout
当然也可以不用CA证书签署服务器证书,可以生成自签名证书
openssl x509 -req -days 3650 -extensions v3_ca -signkey server.key -in server.csr -out server.crt
四、生成客户端证书
1.生成私钥(Private Key)
openssl genrsa -out client.key 2048
2.生成证书签名请求(CSR)
openssl req -new -key client.key -out client.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=MyCompany/OU=Dev/CN=Client/emailAddress=admin@test.com"
验证签名请求信息
openssl req -in client.csr -text -noout
3.生成CA证书签署客户端证书
openssl x509 -req -days 3650 -extensions v3_req -extfile /etc/ssl/openssl.cnf -CA client.crt -CAkey client.key -CAserial client.srl -CAcreateserial -in client.csr -out client.crt
验证证书信息
openssl x509 -in client.crt -text -noout
五、openssl 参数
1.- -extensions v3_ca -extfile /etc/ssl/openssl.cnf
表示要使用 /etc/ssl/openssl.cnf (ubuntu中的位置) 的 v3_ca 配置,表明是 CA 证书
/etc/ssl/openssl.cnf 的 v3_ca 部分,内容如下:
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:true
2.-extensions v3_req -extfile /etc/ssl/openssl.cnf
表示要使用 /etc/ssl/openssl.cnf (ubuntu中的位置) 的 v3_req 配置,表明不是 CA 证书
/etc/ssl/openssl.cnf 的 v3_req 部分,内容如下:
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
3.-CAserial ca.srl -CAcreateserial
-CAserial ca.srl
1) 指定一个文件(这里是 ca.srl),该文件保存了 下一个可用的证书序列号。
2) 每次签发证书后,OpenSSL 会自动将这个序列号加一,并更新该文件。
3) 用于保证每个由 CA 签发的证书都有一个唯一序列号,这是 X.509 标准要求的。
4) 若不使用 -CAserial,默认不会自动生成或维护序列号,可能导致重复的证书序列号。
-CAcreateserial
1) 如果指定的 -CAserial 文件(如 ca.srl)不存在,则创建它并初始化为第一个序列号(通常是 01)。避免因为文件缺失而报错。
六、测试
单向认证命令行:
服务器:
openssl s_server -CAfile ca.crt -cert server.crt -key server.key -accept 22580
客户端:
openssl s_client -CAfile ca.crt -cert client.crt -key client.key -connect 127.0.0.1 -port 443
七、使用
配置单向认证
1.配置 nginx
有了 server.key 和 server.crt 文件后就可以在自己的程序中使用了, 如在 nginx 中使用
server {
listen 443 ssl;
server_name www.test.com;
charset utf-8;
# ssl 证书的 crt 文件路径
ssl_certificate /etc/nginx/server.crt;
# ssl 证书的 key 文件路径
ssl_certificate_key /etc/nginx/server.key;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
2.访问
方式一:
在 curl 命令中,使用 --cacert 参数指定 CA 证书文件
curl --cacert ./ca.crt https://www.test.com
方式二:
ubuntu 客户端导入 CA 根证书
cp ca.crt /usr/local/share/ca-certificates/
update-ca-certificates
curl https://www.test.com
如使用自签名证书出现,且没有把证书导入 /usr/local/share/ca-certificates/,则会出现报错:
zxm@zxm-pc:~$ curl https://www.test.com
curl: (60) SSL certificate problem: self-signed certificate
如使用CA签名的证书出现,,且没有把证书导入 /usr/local/share/ca-certificates/,则会出现报错:
zxm@zxm-pc:~$ curl https://www.test.com
curl: (60) SSL certificate problem: unable to get local issuer certificate
如果 Common Name(CN)与访问的域名不一致的情况下,并且没有配置 SAN 包含指定的域名,例如 CN 配置为 test.com,则会出现报错:
zxm@zxm-pc:~$ curl https://www.test.com
curl: (60) SSL: certificate subject name 'test.com' does not match target host name 'www.test.com'
配置双向认证
有了 server.key,server.crt,ca.crt 文件后就可以在自己的程序中使用了, 如在 nginx 中使用
server {
listen 443 ssl;
server_name www.test.com;
charset utf-8;
# 服务端证书配置
ssl_certificate /etc/nginx/server.crt;
ssl_certificate_key /etc/nginx/server.key;
# 双向认证配置
ssl_client_certificate /etc/nginx/ca.crt;
ssl_verify_client on;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
在 curl 命令中,使用 --cacert 参数指定 CA 证书文件,--cert 指定客户端证书,--key 指定客户端密钥
curl --cacert ./ca.crt --cert ./client.crt --key ./client.key https://www.test.com
如果没有指定 --cert 和 --key,则会出现报错:
zxm@zxm-pc:~$ curl --cacert ./ca.crt https://www.test.com
<html>
<head><title>400 No required SSL certificate was sent</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>No required SSL certificate was sent</center>
<hr><center>nginx/1.24.0</center>
</body>
</html>