https(SSL)双向认证
HTTPS(SSL)双向认证是一种身份验证机制,它要求客户端和服务器在建立安全连接时都相互验证对方的身份。这种机制确保了双方都能够确认对方的身份,从而增加了通信的安全性
单向认证流程
-
客户端发起建立HTTPS连接请求,将SSL协议版本的信息发送给服务器端;
-
服务器端将本机的公钥证书(server.crt)发送给客户端;
-
客户端读取公钥证书(server.crt),取出了服务端公钥;
-
客户端生成一个随机数(密钥R),用刚才得到的服务器公钥去加密这个随机数形成密文,发送给服务端;
-
服务端用自己的私钥(server.key)去解密这个密文,得到了密钥R
-
服务端和客户端在后续通讯过程中就使用这个密钥R进行通信了。
双向认证流程
-
客户端发起建立HTTPS连接请求,将SSL协议版本的信息发送给服务端;
-
服务器端将本机的公钥证书(server.crt)发送给客户端;
-
客户端读取公钥证书(server.crt),取出了服务端公钥;
-
客户端将客户端公钥证书(client.crt)发送给服务器端;
-
服务器端使用根证书(root.crt)解密客户端公钥证书,拿到客户端公钥;
-
客户端发送自己支持的加密方案给服务器端;
-
服务器端根据自己和客户端的能力,选择一个双方都能接受的加密方案,使用客户端的公钥加密后发送给客户端;
-
客户端使用自己的私钥解密加密方案,生成一个随机数R,使用服务器公钥加密后传给服务器端;
-
服务端用自己的私钥去解密这个密文,得到了密钥R
-
服务端和客户端在后续通讯过程中就使用这个密钥R进行通信了。
单向认证和双向认证的区别
单向认证:
只有一个对象校验对端的证书合法性。
通常都是client来校验服务器的合法性。那么client需要一个ca.crt,服务器需要server.crt,server.key
双向认证:
相互校验,服务器需要校验每个client,client也需要校验服务器。
server 需要 server.key 、server.crt 、ca.crt
client 需要 client.key 、client.crt 、ca.crt
Nginx配置ssl双向认证
CA与自签名(根证书)
openssl genrsa -des3 -out ca.key 4096
生成一个4096位的RSA私钥,并使用DES3算法对其进行加密。加密后的私钥会被保存到ca.key文件中
openssl genrsa -out ca.key 4096
生成一个4096位的RSA私钥,不加密生成的私钥,就将其保存到ca.key文件中
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
创建一个新的自签名X.509证书,得到一个名为ca.crt的自签名证书,它使用ca.key中的私钥进行签名。
-new:表示创建一个新的证书请求。
-x509:表示自签名证书请求,即使用相同的私钥来签署证书。
-days 365:设置证书的有效期为365天。
-key ca.key:指定用于签署证书的私钥文件。
-out ca.crt:指定输出证书文件的名称。
生成客户端证书
openssl genrsa -out client.key 4096
生成一个4096位的RSA私钥,并将其保存到client.key文件中。4096位是目前推荐的密钥长度
openssl req -new -key client.key -out client.csr
创建一个新的证书请求(CSR)。-new参数指示生成新的请求,-key client.key指定了用于生成CSR的私钥文件,-out client.csr指定了输出CSR文件的名称。在创建CSR时,openssl会提示输入一些信息,如国家、组织、通用名等,这些信息将包含在CSR中
openssl x509 -req -days 365 -in client.csr -CA /root/cert/ca.crt -CAkey /root/cert/ca.key -set_serial 01 -out client.crt
使用之前生成的CA证书(ca.crt)和私钥(ca.key)来签署客户端的CSR,需要指定ca.crt和ca.key的绝对路径并生成一个客户端证书(client.crt)。-req参数表示输入是一个CSR,-days 365设置证书的有效期为365天,-in client.csr指定CSR输入文件,-CA ca.crt和-CAkey ca.key分别指定CA证书和私钥文件,-set_serial 01设置证书的序列号,-out client.crt指定输出证书文件的名称。
openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12
将客户端证书(client.crt)和私钥(client.key)打包成一个PKCS#12格式的文件(client.p12)。
PKCS#2是一种二进制格式,通常用于存储私钥和证书。-export参数表示导出PKCS12文件,-clcerts表示只包含客户端证书,-in client.crt和-inkey client.key分别指定证书和私钥的输入文件,-out client.p12指定输出PKCS12文件的名称。
openssl pkcs12 -in client.p12 -out all.pem -nodes
将PKCS12文件(client.p12)转换为PEM格式,并将私钥和证书保存到all.pem文件中。-in client.p12指定输入PKCS12文件,-out all.pem指定输出PEM文件的名称,-nodes参数表示在输出文件中不包含私钥的加密密码,即私钥将以明文形式存储在PEM文件中
生成服务端证书
openssl genrsa -out server.pem 2048
生成一个1024位的RSA私钥,并将其保存到server.pem文件中
openssl rsa -in server.pem -out server.key
从server.pem文件中提取私钥,并将其保存到server.key文件中
openssl req -new -key server.pem -out server.csr
创建一个新的证书请求(CSR)。-new参数指示生成新的请求,-key server.pem指定了用于生成CSR的私钥文件,-out server.csr指定了输出CSR文件的名称。在创建CSR时,openssl会提示输入一些信息,如国家、组织、通用名等,这些信息将包含在CSR中
openssl x509 -req -sha256 -in server.csr -CA /root/cert/ca.crt -CAkey /root/cert/ca.key -CAcreateserial -days 3650 -out server.crt
使用之前生成的CA证书(/root/cert/ca.crt)和私钥(/root/cert/ca.key)来签署服务器的CSR,并生成一个自签名证书(server.crt)。-req参数表示输入是一个CSR,-sha256指定使用SHA-256哈希算法,-in server.csr指定CSR输入文件,-CA /root/cert/ca.crt和-CAkey /root/cert/ca.key分别指定CA证书和私钥文件,-CAcreateserial表示如果序列号文件不存在,则创建它,-days 3650设置证书的有效期为3650天(约10年),-out server.crt指定输出证书文件的名称
Nginx配置
client.p12等所有密码都为123456
服务端和客户端证书都是基于ca证书去创建的
server {
listen 443 ssl ;
ssl_certificate /usr/local/nginx/server/server.crt; #server证书公钥
ssl_certificate_key /usr/local/nginx/server/server.key; #server私钥
ssl_client_certificate /usr/local/nginx/cert/ca.crt; # 根级证书公钥,用于验证各个二级client
ssl_verify_client on; #开启客户端证书验证
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location = /50x.html {
root html;
}
}
浏览器未配置客户端证书访问
错误的请求,提示客户端没有发送服务器期望的客户端证书