背景:客户项目这边都是专网环境,也就是全部走的是内网,前端页面里面用到一个组件必须采用安全HTTPS,而我一想这这种https证书场景都是用在公网环境下大部分,内网环境有点麻烦,因为自签证书要把这证书分发到每台客户端上,所以我们通过Windows域控的方式统一对下属计算机进行证书分发保证可用性。 HTPS原理 HTTPS之所以安全,主要是因为它采用了SSL证书的信任机制。这个机制简单来说就是通过两种证书来实现的:CA证书和服务器证书。 服务器证书由网站所有者获取并配置在服务器上,它包含了一对公钥和私钥。当浏览器向服务器发起请求时,服务器会用私钥加密响应,并将密文和公钥一起发送给浏览器。浏览器使用服务器证书中的公钥解密密文,然后与明文进行对比,以确保响应数据未被篡改。 但是,如果有人拦截了通信并伪造了一对有效的公钥和私钥,就能够欺骗浏览器。为了防止这种情况,引入了CA证书。CA证书由受信任的证书颁发机构签发,其中包含了公钥。服务器证书中的公钥是通过CA证书的私钥加密得到的。浏览器在收到服务器证书后,会使用内置的CA证书来验证服务器证书的真实性,如果验证失败,就说明可能存在中间人攻击。 证书的结构如下:
证书的结构如下:
自签证书创建流程:
我这边用openssl工具生成
创建CA证书: 第一步创建是秘钥,这个是CA根证书,之后所有的东西都是来自这个东东。
openssl genrsa -out myCA.key 2048 #通过rsa算法生成2048位长度的秘钥
通过秘钥加密机构信息形成公钥:
openssl req -new -x509 -key myCA.key -out myCA.cer -days 36500
# 公钥包含了机构信息,在输入下面的指令之后会有一系列的信息输入,这些信息便是机构信息,公司名称地址什么的
# 这里还有一个过期信息,CA证书也会过期,openssl默认是一个月,我们直接搞到100年吧
创建服务器证书:
在得到CA证书之后,需要通过openssl工具对证书进行转换得到公钥(.crt文件)和密钥(.key文件),无论CA证书是怎么来的到这里之后就没有任何区别了,服务器证书的制作流程相较CA证书要复杂一点点。
第一步通过openssl工具创建服务器的秘钥:
openssl genrsa -out server.key 2048 # 通过RSA算法生成长度2048位的秘钥
第二步这里是创建一个签名请求
需要将服务器信息写入到请求文件之中,然后通过CA机构证书对请求签名形成服务器公钥,这一步要难点。
这里涉及了一些https证书的配置问题。首先,openssl默认生成的证书是V1版本的,但一些浏览器认为这不安全,因此建议使用V3版本。另外,openssl生成的证书默认没有包含V3的subjectAltName字段,这个字段包含了证书对应的IP地址或域名,可以使用通配符。为了解决这些问题,需要通过以下配置文件进行设置。
vim openssl.cnf
tsa_policy2 = 1.2.3.4.5.6
tsa_policy3 = 1.2.3.4.5.7
[ ca ]
default_ca = CA_default # The default ca section
[ CA_default ]
dir = ./demoCA # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem# The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
default_days = 3650 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = default # use public key default MD
preserve = no # keep passed DN ordering
policy = policy_match
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
string_mask = utf8only
req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = CN
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = GuangDong
localityName = Locality Name (eg, city)
localityName_default = GuangDong
0.organizationName = Organization Name (eg, company)
0.organizationName_default = GOMYCK
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default=Technology.U
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = caijintian.cn
commonName_max = 64
emailAddress = Email Address
emailAddress_default = jintian.cai@outlook.com
emailAddress_max = 64
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name
[ usr_cert ]
basicConstraints=CA:FALSE
nsCertType = client, email, objsign
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
nsComment = "OpenSSL Generated Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
[ svr_cert ]
basicConstraints=CA:FALSE
nsCertType = server
keyUsage = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment, keyAgreement
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
extendedKeyUsage = serverAuth,clientAuth
[ v3_req ]
subjectAltName = @alt_names
# 这里是关键配置,需要将里面配置为最终服务端需要的域名或者IP
[ alt_names ]
IP.1 = 172.20.1.120
#IP.2 = 172.20.1.15
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = CA:true
[ crl_ext ]
authorityKeyIdentifier=keyid:always
[ proxy_cert_ext ]
basicConstraints=CA:FALSE
nsComment = "OpenSSL Generated Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
[ tsa ]
default_tsa = tsa_config1 # the default TSA section
[ tsa_config1 ]
dir = ./demoCA # TSA root directory
serial = $dir/tsaserial # The current serial number (mandatory)
crypto_device = builtin # OpenSSL engine to use for signing
signer_cert = $dir/tsacert.pem # The TSA signing certificate (optional)
certs = $dir/cacert.pem # Certificate chain to include in reply (optional)
signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
default_policy = tsa_policy1 # Policy if request did not specify it (optional)
other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
digests = md5, sha1 # Acceptable message digests (mandatory)
accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
clock_precision_digits = 0 # number of digits after dot. (optional)
ordering = yes # Is ordering defined for timestamps? (optional, default: no)
tsa_name = yes # Must the TSA name be included in the reply? (optional, default: no)
ess_cert_id_chain = no # Must the ESS cert id chain be included? (optional, default: no)
将上面的配置内容保存为openssl.cnf放到生成的服务器证书文件的目录下(注意:修改alt_names里面的域名或者IP为最终部署需要的地址,支持通配符)
然后执行创建签名申请文件即可,执行运行:
openssl req -config openssl.cnf -new -out server.req -key server.key
# 在输入Common Name(CN)最好直接输入服务器的IP地址或者域名。
通过CA机构证书对服务器证书进行签名认证
penssl x509 -req -extfile openssl.cnf -extensions v3_req -in server.req -out server.cer -CAkey myCA.key -CA myCA.cer -days 36500 -CAcreateserial -CAserial serial