概述
PKI指的是Public Key Infrastructure,即公钥基础设施。这是一种利用公钥加密技术为电子商务的开展提供一套安全基础平台的技术和规范。PKI的主要目的是管理密钥和证书,通过采用公钥加密和数字签名服务,建立一个安全的网络环境。它能够为所有网络应用提供加密和数字签名等密码服务及所必需的密钥和证书管理体系。简单来说,PKI就是利用公钥理论和技术建立的提供安全服务的基础设施,用户可利用PKI平台提供的服务进行安全的电子交易、通信和互联网上的各种活动。
关注公众号【可为编程】回复【加群】进入技术群一起成长学习!!!
关注公众号【可为编程】回复【面试】领取年度最新面试题大全!!!
ECC加密算法具有高安全性、低消耗、运算速度快的特点,在数字签名领域有良好的应用前景,那么我们今天就来探讨一下ECC加密算法在数字签名中的应用。ECC算法,目前主要用于签名/验签和生成DH会话秘钥。下面的表格展示了在相同的安全登记下,ECC和RSA秘钥长度的对比:
RSA size(in bits) | ECC size(in bits) |
---|---|
1024 | 160 |
2048 | 224 |
3072 | 256 |
7680 | 384 |
管理证书:certmgr.msc
列出可用ECC曲线:openssl ecparam -list_curves
(注意这里需要在Linux系统中安装openssl开源组件)
我们使用 prime256v1 生成ECC秘钥对。
关注公众号【可为编程】回复【面试】领取年度最新面试题大全!!!
1、使用ECC key 生成CA 证书
我们需要使用CA证书来签名服务器和客户端的证书,使用ECC私钥生成CA 根证书,为此我们创建几个目录,用来存储CA证书,秘钥,索引数据。
注意:以上目录创建在/root/ECC/tls目录下。
$mkdir /root/ECC/tls
$cd /root/ECC/tls
$mkdir certs private
$echo 00 > /root/ECC/serial
在/root/ECC/目录下,我们需要一个openssl 配置文件,在/etc/pki/CA目录下有此配置文件,可以拷贝过来。或者直接复制下面内容创建openssl.cnf文件。
2、openssl.cnf文件配置
首先配置配置openssl.cnf文件:
[ ca ] # `man ca` default_ca = CA_default
[ CA_default ]
Directory and file locations.
dir = /root/ECC#这里改成实际目录
certs = $dir/certs
crl_dir = $dir/crl
new_certs_dir = $dir/newcerts
database = $dir/index.txt
serial = $dir/serial
RANDFILE = $dir/private/.randThe root key and root certificate.
private_key = $dir/private/ca.key.pem
certificate = $dir/certs/ca.cert.pemFor certificate revocation lists.
crlnumber = $dir/crlnumber
crl = $dir/crl/ca.crl.pem
crl_extensions = crl_ext
default_crl_days = 30SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
name_opt = ca_default
cert_opt = ca_default
default_days = 375
preserve = no
policy = policy_strict[ policy_strict ]
The root CA should only sign intermediate certificates that match.
See the POLICY FORMAT section of
man ca
.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[ policy_loose ]
Allow the intermediate CA to sign a more diverse range of certificates.
See the POLICY FORMAT section of the
ca
man page.countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional[ req ]
Options for the
req
tool (man req
).default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = utf8onlySHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
Extension to add when the -x509 option is used.
x509_extensions = v3_ca
req_extensions = v3_req
[ req_distinguished_name ]
See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
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
emailAddress = Email AddressOptionally, specify some defaults.
countryName_default = CN
stateOrProvinceName_default = China
localityName_default = BJ
0.organizationName_default = JD
#organizationalUnitName_default = pt.itage
#emailAddress_default =[ v3_req ]
Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names[ alt_names ]
DNS.1 = xxx.com //一定要注意这里,可以改成自己的域名
DNS.2 = pt.xxx.com //一定要注意这里,可以改成自己的域名
DNS.3 = localhost //一定要注意这里,可以改成自己的域名
IP.1 = 192.168.190.131//一定注意这里,改成自己的IP地址
关注公众号【可为编程】回复【加群】进入技术群一起成长学习!!!
关注公众号【可为编程】回复【面试】领取年度最新面试题大全!!![ v3_ca ]
Extensions for a typical CA (
man x509v3_config
).subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign[ v3_intermediate_ca ]
Extensions for a typical intermediate CA (
man x509v3_config
).subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign[ usr_cert ]
Extensions for client certificates (
man x509v3_config
).basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection[ server_cert ]
Extensions for server certificates (
man x509v3_config
).basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names[ crl_ext ]
Extension for CRLs (
man x509v3_config
).authorityKeyIdentifier=keyid:always
[ ocsp ]
Extension for OCSP signing certificates (
man ocsp
).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning
上面配置文件要注意几个地方:
[ CA_default ]
# Directory and file locations.
dir = /root/ECC#这里改成实际目录
可以加入一些公司信息和城市信息:
# Optionally, specify some defaults.
countryName_default = CN
stateOrProvinceName_default = China
localityName_default = BJ
0.organizationName_default = JD
#organizationalUnitName_default = pt.itage
#emailAddress_default =
这里配置IP和域名,一定要配置好,不然会找不到对应的IP或域名,导致证书验签不通过,在nginx配置后浏览器会提示非不安全的请求访问。
[ alt_names ]
DNS.1 = xxx.com //一定要注意这里,可以改成自己的域名
DNS.2 = pt.xxx.com //一定要注意这里,可以改成自己的域名
DNS.3 = localhost //一定要注意这里,可以改成自己的域名
IP.1 = 192.168.190.131//一定注意这里,改成自己的IP地址
生成ECC私钥
$openssl ecparam -out private/ec-cakey.pem -name prime256v1 -genkey
生成秘钥时,openssl默认仅存储权限的名字:
$openssl ecparam -in private/ec-cakey.pem -text -noout
生成CA证书
使用上一步生成的CA私钥,生成CA证书
openssl req -new -x509 -days 36500 -config openssl.cnf -extensions v3_ca -key private/ec-cakey.pem -out certs/ec-cacert.pem
接下来,我们可以验证下CA证书的内容和使用的签名算法
openssl x509 -noout -text -in certs/ec-cacert.pem | grep -i algorithm
可以看到,我们使用的是ECDSA签名算法来生成我们的CA证书,而不是使用的RSA。
关注公众号【可为编程】回复【加群】进入技术群一起成长学习!!!
关注公众号【可为编程】回复【面试】领取年度最新面试题大全!!!
使用私钥验证CA证书
如果想使用私钥(包含ECDSA key)验证证书:
$openssl x509 -noout -pubkey -in certs/ec-cacert.pem
类似地,我们可以从私钥导出公钥:
$openssl pkey -pubout -in private/ec-cakey.pem
$openssl pkey -pubout -in private/ec-cakey.pem -ou certs/ec-capub.pem
可以看到,生成的公钥是相同的。
3、生成服务端证书
现在我们可以使用ECC私钥生成服务端证书,为了存储服务端证书,我们创建目录:
$mkdir /root/ECC/server_certs/
$cd /root/ECC/server_certs/
生成服务端证书的ECC私钥
我们再一次使用曲线prime256v1 生成ECC的私钥'
openssl ecparam -out server.key -name prime256v1 -genkey
验证曲线:
openssl ecparam -in server.key -text -noout
服务端生成CSR
我们的CA证书生成时,使用的是 openssl.cnf 里的v3_ca 扩展选项
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
CA证书会匹配 Country Name, state or Province Name and Organization Name. 所以服务端证书的CSR请求里的值必须匹配CA证书里相应的值。
Common Name 必须是 服务端的主机名(hostname), 客户端与服务端认证时会使用这个Common Name.
生成CSR请求:
openssl req -new -key server.key -out server.csr -sha256 -config /root/ECC/openssl.cnf
服务端生成CA签名的证书
现在我们使用ECC CA 私钥,CA证书,对server.csr进行签名,生成服务端证书:
关注公众号【可为编程】回复【加群】进入技术群一起成长学习!!!
关注公众号【可为编程】回复【面试】领取年度最新面试题大全!!!
openssl ca -keyfile /root/ECC/tls/private/ec-cakey.pem -cert /root/ECC/tls/certs/ec-cacert.pem -in server.csr -days 36500 -out server.crt -config /root/ECC/openssl.cnf -extensions v3_req
验证服务端证书
使用CA证书验证服务端证书
openssl verify -CAfile /root/ECC/tls/certs/ec-cacert.pem server.crt
我们也可以验证服务端证书的签名算法,确保使用的是ECC私钥。
openssl x509 -noout -text -in server.crt | grep -i algorithm
验证index.txt
验证index.txt包含服务端证书的信息,这个服务端证书是我们使用CA证书签名的。01是我们再开始部分写入的序列号,每次签名,这个序列号都会自加1.
4、在客户端生成CA签名的证书
我们新建一个目录来存储客户端生成的CA证书
mkdir /root/ECC/client_cert/
cd /root/ECC/client_cert/
生成客户端证书的ECC私钥
openssl ecparam -out client.key -name prime256v1 -genkey
验证私钥的曲线名称:
$openssl ecparam -in client.key -text -noout
生成客户端证书的CSR请求
openssl req -new -key client.key -out client.csr -sha256 -config /root/ECC/openssl.cnf
生成客户端证书
$openssl ca -keyfile /root/ECC/tls/private/ec-cakey.pem -cert /root/ECC/tls/certs/ec-cacert.pem -days 36500 -in client.csr -out client.crt -config /root/ECC/openssl.cnf -extensions v3_req
5、问题汇总
openssl TXT_DB error number 2 failed to update database
产生的原因是:
This thing happens when certificates share common data. You cannot have two
certificates that look otherwise the same.
方法一:
修改demoCA下index.txt.attr
unique_subject = yes
改为
unique_subject = no
查看index.txt
6、加密文件转换命令汇总
crt转pem
openssl x509 -in ca.crt -out ca.pem -outform PEM
pem转crt
openssl x509 -in fullchain.pem -out fullchain.crt
pem转key
openssl rsa -in privkey.pem -out privkey.key
ECC算法:key转pem
openssl ec -in server.key -out server_key_to_pem.pem
openssl ec -in client.key -out client_key_to_pem.pem
rsa算法:key转pem
openssl rsa -in server.key -out server_key_to_pem.pem
openssl rsa -in client.key -out client_key_to_pem.pem
key转pkcs8的key
openssl pkcs8 -topk8 -inform PEM -in client.key -outform pem -nocrypt -out client-key-pkcs8-ecc.pem
openssl pkcs8 -topk8 -inform PEM -in server.key -outform pem -nocrypt -out server-key-pkcs8-ecc.pem
生成truststore
keytool -import -alias one_double_truststore -file tls/certs/ec-cacert.pem -keystore one_double_truststore -storepass 123456
生成keystore
openssl pkcs12 -export -in client.crt -inkey client.key -out alone_keystore.p12 -passout pass:"123456"
openssl pkcs12 -export -in client.crt -inkey client.key -out double_keystore.p12 -passout pass:"123456"