Pages

Saturday, 17 April 2021

TCP(GRPC)/HTTPS中,TLS单向和双向认证

目前,浏览器中开启HTTPS是比较简单的事情。首先我们需要一个域名,然后找一家可信CA机构申请证书并将证书安装到服务器(例如:RapidSSL、Trustwave SSL、Let’s Encrypt等)。但对TCP协议的服务使用self-signed证书我们应该如何完成?

证书的分类

验证方式

  • DV SSL证书(域名验证)
  • OV SSL证书(企业验证)
  • EV SSL证书(企业增强/扩展验证)

功能分类

  • UCC/SAN SSL证书(多域名)
  • SGC SSL证书(强加密)
  • Wildcard SSL证书(通配符)
  • Code Signing SSL证书(代码签名)

认证流程

  • one-way authentication(单向认证)
  • two-way(mutual) authentication(双向认证)

浏览器中大部分应用使用单向认证,即服务器认证客户端,客户端无需认证服务器。大型企业有很多域名一般使用OV SSL和SAN SSL证书,而个人网站则使用DV SSL证书。

证书使用

什么时候使用可信CA签发证书,什么时候使用自签证书? 什么时候使用单向证书或双向证书。

这些都应根据应用的实际业务而定,浏览器应用中使用可信CA签发的证书,这样浏览器访问你的网站时就不会提示not secure错误,这是因浏览器中预置可信CA机构的CA证书。这也不是绝对的,例如12306网站就使用的自签证书,你会看到not secure错误,导入12306网站的CA证书可以消除这个提示。自签证书不是说比可信CA机构签发的证书有更高的安全性。因为加密算法都是公开的,而是私钥文件自己保管。对于安全性高的场景,例如金融行业对账,就应该使用自签和双向认证。

证书自签

生成自签证书脚本

#!/bin/sh

mkdir -p {certs,crl,newcerts}
touch index.txt
echo 1000 > serial


# CA private key (unencrypted)
openssl genrsa -out ca.key 4096
# Certificate Authority (self-signed certificate)
openssl req -config openssl.cnf -new -x509 -days 3650 -sha256 -key ca.key -extensions v3_ca -out ca.crt -subj "/CN=fake-ca"

# Server private key (unencrypted)
openssl genrsa -out server.key 2048
# Server certificate signing request (CSR)
openssl req -config openssl.cnf -new -sha256 -key server.key -out server.csr -subj "/CN=fake.grpc"
# Certificate Authority signs CSR to grant a certificate
openssl ca -batch -config openssl.cnf -extensions server_cert -days 365 -notext -md sha256 -in server.csr -out server.crt -cert ca.crt -keyfile ca.key

# Client private key (unencrypted)
openssl genrsa -out client.key 2048
# Signed client certificate signing request (CSR)
openssl req -config openssl.cnf -new -sha256 -key client.key -out client.csr -subj "/CN=fake.client"
# Certificate Authority signs CSR to grant a certificate
openssl ca -batch -config openssl.cnf -extensions usr_cert -days 365 -notext -md sha256 -in client.csr -out client.crt -cert ca.crt -keyfile ca.key



rm *.csr

自签证书配置

SAN =

[ ca ]
# `man ca`
default_ca = CA_default

[ CA_default ]
# Directory and file locations.
dir = .
certs = $dir/certs
crl_dir = $dir/crl
new_certs_dir = $dir/newcerts
database = $dir/index.txt
serial = $dir/serial
# certificate revocation lists.
crlnumber = $dir/crlnumber
crl = $dir/crl/intermediate-ca.crl
crl_extensions = crl_ext
default_crl_days = 30
default_md = sha256

name_opt = ca_default
cert_opt = ca_default
default_days = 375
preserve = no
policy = policy_loose

[ policy_loose ]
# Allow the CA to sign a range of certificates.
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ req ]
# `man req`
default_bits = 4096
distinguished_name = req_distinguished_name
string_mask = utf8only
default_md = sha256

[ req_distinguished_name ]
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit Name
commonName = Common Name

# Certificate extensions (`man x509v3_config`)

[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ usr_cert ]
basicConstraints = CA:FALSE
nsCertType = client
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth

[ server_cert ]
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = $ENV::SAN

No comments:

Post a Comment