SSL/TLS证书格式解释以及转换cmd
X.690,它是ITU-T标准,规定了几种ASN.1编码格式:
Basic Encoding Rules (BER)
Canonical Encoding Rules (CER)
Distinguished Encoding Rules (DER)
一、名词解释
1、.der (Distinguished Encoding Rules)区分编码规则
DER 是ASN.1 众多编码方案中的一个。DER 是 BER 的子集,对数据产生一个唯一的序列化表示。(其实是二进制编码)
DER 格式的证书是二进制形式,存储在以 .der 和 .cer 为扩展名的文件中。这些证书大部分使用在基于java的web服务器上。
而一般 PEM 文件使用的是 base64 进行编码,所以可以把 DER 编码的文件转换成 PEM 文件。
2、.pem (Privacy-Enhanced Mail)隐私增强邮件
PEM 是一种容器格式,可以将服务端证书(server certificate),中间证书(intermediate certificate),公钥(public key),私钥(private key)包含在一个文件中。用于存储和发送加密密钥,证书和其他数据。可能仅包含公钥证书,也可以包含完整的证书链(包括公玥,私钥,和根证书)。
服务端证书和中间证书也可以分别存放在 .crt 和 .cer 两个文件中。私钥可以单独在一个 .key 文件中。
PEM 格式则使用 base64 编码二进制数据,所以你可以用文本编辑器打开它,例如notepad,微软的word等等。
PEM文件的文件格式:
-----BEGIN (label)-----
/* data */
-----END (label)-----
label 决定了被编码消息的类型,通常这些类型有如下一些:
"CERTIFICATE", "CERTIFICATE REQUEST", "PRIVATE KEY", "ENCRYPTED PRIVATE KEY" and "X509 CRL".
---- BEGIN CERTIFICATE----
/* 证书 */
----END CERTIFICATE----
---- BEGIN RSA PRIVATE KEY-----
/* 私钥 */
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE REQUEST-----
/* CSR */
-----END CERTIFICATE REQUEST-----
......
PEM 格式的数据通常存储在以 .pem, .cer, .crt(证书) 或者 .key(公钥或私钥) 为后缀的文件中。
3、.key
.key 其实就是一个 PEM 格式只包含 公钥或私玥 的文件,.key 作为文件名只是作为一个明显的别名。
4、.csr (certificate signing request )证书签名请求
.csr 是证书请求文件,是由 RFC 2986定义的PKCS10格式,包含部分/全部的请求证书的信息,比如,主题, 机构,国家等,并且包含了请求证书的公玥,这些被CA中心签名后返回一张证书。返回的证书是公钥证书(只包含公玥不含私钥)。
证书签名请求是申请人向证书颁发机构发送的一条消息,用于申请数字身份证书。
有 CSR 必定有 KEY,是成对的,CSR 最终变成为证书 crt,和私钥 key 配对使用。证书下发后,CSR 就没有用了,只是在交时候需要。
5、X.509
Public-Key Infrastructure (X.509) (pkix)
在密码学中,X.509 公钥证书格式的标准,也应用于许多Internet协议,包括TLS/SSL,它是HTTPS的基础。
一个X.509证书包含一个公钥和一个标识(主机名、组织或个人),由证书颁发机构签名或自签名。
X.509 还定义了证书撤销列表,这是一种分发被签名机构认为无效的证书信息的方法,以及认证路径验证算法,该算法允许证书由中间CA证书签名,而中间CA证书又由其他证书签名,最终到达信任锚。
X.509 DER 编码(ASCII)的后缀是: .DER .CER .CRT
X.509 PAM 编码(Base64)的后缀是: .PEM .CER .CRT
.cer/.crt是用于存放证书,它是2进制形式存放的,不含私钥。
.pem跟crt/cer的区别是它以Ascii来表示。
6、PKCS (Public Key Cryptography Standards)(公钥密码学标准)
常见的有PKCS#7,PKCS#10,PKCS#12,其他的格式忽略吧
6.1、PKCS#7:
Cryptographic Message Syntax Standard
加密消息语法标准。
扩展名:.p7b .p7c .spc
使用 base64 编码,用于在PKI下签名和/或加密消息,还用于证书分发(例如作为对PKCS #10消息的响应)。只有证书可以存储在这种格式的文件中(例如作为对 “PKCS #10证书签名请求标准” 消息的响应),私钥则不可以。
p7r是CA对证书请求的回复,只用于导入。
p7b以树状展示证书链(certificate chain),同时也支持单个证书,不含私钥。
P7B证书包含在BEGIN (label) END (label)之间:
-----BEGIN PKCS7-----
/* P7B证书 */
-----END PKCS7-----
6.2、PKCS #8:
Private-Key Information Syntax Standard
私钥信息语法标准,用于携带私有证书密钥对(加密或未加密)。
6.3、PKCS#10:
Certification Request Standard
证书签名请求标准,发送给认证机构要求认证公钥的消息的格式。
p10是证书请求
6.4、PKCS#12:
Personal Information Exchange Syntax Standard
个人信息交换语法标准。
扩展名:.pfx .p12,使用二进制编码。
PKCS#12文件通常用来存储 服务端证书,中间证书,私钥,并使用基于密码的对称密钥进行保护。PFX 是 PKCS#12的前身。
跟pem文件不同的是,它的内容是完全加密的,用openssl可以把其转换成包含公钥和私钥的 .pem 文件。
命令: openssl pkcs12 -in file-to-convert.p12 -out converted-file.pem -nodes
这类证书主要使用在Windows平台。
二、SSL Certificate (编码)格式
SSL Certificate实际上就是X.509 Certificate。X.509使用名为 Abstract Syntax Notation One (ASN.1)的通用语言来描述certificate的数据结构。
X.509 certificate 有几种不同的格式,例如 PEM,DER,PKCS#7 和 PKCS#12。 PEM和PKCS#7格式使用Base64 ASCII编码,而DER和PKCS#12使用二进制编码。
如下图就展示了X.509证书的编码方式和文件扩展名。
参考来源:
> https://blog.csdn.net/yetugeng/article/details/100629159
> https://blog.csdn.net/xkdlzy/article/details/113380587?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_default&utm_relevant_index=1
三、证书格式间的转换命令
1、参数说明:
-nodes:一直对私钥不加密。
-noout:不打印参数编码的版本信息。
-clcerts:仅仅输出客户端证书,不输出CA证书。
-cacerts:仅仅输出CA证书,不输出客户端证书。
-nocerts:不输出任何证书。
-nokeys:不输出任何私钥信息值。
(参考来源:https://blog.free-tools.cn/archives/1171)
2、pfx提取 证书和秘钥:
#2.1 .pfx 生成证书和秘钥:(常用)
openssl pkcs12 -in server.pfx
-nodes -out prikey_and_ca_bundle.pem //生成PRIVATE KEY和完整证书链信息
-clcerts -nodes -out prikey_and_clcert.pem //生成PRIVATE KEY和客户端证书信息
#输出数据内容:
-----BEGIN CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
#2.2 生成PRIVATE KEY
-nocerts -nodes -out prikey.key
#输出数据内容:
-----BEGIN PRIVATE KEY-----(同2.1)
#2.3 生成EN PRIVATE KEY
-nocerts -out en_prikey.key //输入pfx密码后,需要再输入 PEM pass phrase
#输出数据内容:
-----BEGIN ENCRYPTED PRIVATE KEY-----
#2.4 生成客户端证书信息
-clcerts -nokeys -out clcert.crt
#输出数据内容:
-----BEGIN CERTIFICATE-----(同2.1)
#2.5 生成EN PRIVATE KEY和客户端证书信息
-clcerts -out clcert_and_en_prikey.pem
#输出数据内容:
-----BEGIN CERTIFICATE-----(同2.1)
-----BEGIN ENCRYPTED PRIVATE KEY-----
#2.6 生成RSA PRIVATE KEY
openssl rsa -in en_prikey.key -out rsa_prikey.key //需要输入 pass phrase
#输出数据内容:
-----RSA PRIVATE KEY-----
#2.7 客户端证书以 der 编码
openssl x509 -outform der -in clcert.crt -out clcert_der.crt
#输出数据内容:
二进制数据
PEM编码的证书签名请求文件: -----BEGIN CERTIFICATE REQUEST-----
3、合成 .pfx
思路:使用crt + key 用来生成pfx证书文件。
openssl pkcs12 -export -out server.pfx -inkey prikey.key -in ***.crt
openssl pkcs12 -export -out server.pfx -inkey public.key -in crt.crt //unable to load private key
openssl pkcs12 -export -out server.pfx -inkey pair.key -in cert.pem //success
openssl pkcs12 -export -out server.pfx -inkey private.key -in cert.pem //success
提示输入 .key文件的密码
提示输入即将生成的 .pfx文件的密码(需要输入两次)
若成功,会生成 server.pfx文件
4、另一种提取私钥的方法,从公钥对中提取:
从pfx证书中提取密钥信息,并转换为key格式(pfx使用pkcs12模式补足) 1、提取密钥对(如果pfx证书已加密,会提示输入密码) openssl pkcs12 -in server.pfx -nocerts -nodes -out prikey.key BEGIN PRIVATE KEY //1,和 4 相同,但比 4 多一些 Attributes 2、从密钥对提取公钥 openssl -in prikey.key -pubout -out public.key BEGIN PUBLIC KEY //或者 //openssl rsa -in en_prikey.key -pubout -out public.key //两者输出一致 3、从密钥对提取RSA私钥 openssl rsa -in pair.key -out private_rsa.key BEGIN RSA PRIVATE KEY 4、因为RSA算法使用的是 pkcs8 模式补足,需要对提取的私钥进一步处理得到最终私钥 openssl pkcs8 -topk8 -inform PEM -in private_rsa.key -outform PEM -nocrypt -out private.key BEGIN PRIVATE KEY //4,和 1 相同
参考:
> https://blog.51cto.com/u_15288038/2985496
5、查看pfx的信息,一般会包括 [CERTIFICATE][ENCRYPTED PRIVATE KEY]
openssl pkcs12 -in xxx.pfx -info
6、从cer证书中提取公钥信息
openssl x509 -in xxxx.cer -pubkey -out pub.key
//输出
-----BEGIN PUBLIC KEY-----
****
-----END PUBLIC KEY-----
-----BEGIN CERTIFICATE-----
***
-----END CERTIFICATE-----
7、查看服务器返回的证书链,加密协议,加密套件
openssl s_client -connect www.baidu.com:443 -showcerts
8、本地生成测试证书
openssl genrsa -out client.key 2048 openssl req -new -x509 -key client.key -out client.crt -days 365
9、生成自签名证书
自签名:
# 1.生成私钥
$ openssl genrsa -out server.key 2048
# 2.生成 CSR (Certificate Signing Request)
$ openssl req -subj "/C=CN/ST=test/L=test/O=test/OU=test/CN=域名orIP/emailAddress=test@123.com" -new -key server.key -out server.csr
# 3.生成自签名证书
$ openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt
私有 CA 签名:
# 1.创建 CA 私钥
$ openssl genrsa -out ca.key 2048
# 2.生成 CA 的自签名证书
$ openssl req -subj "/C=CN/ST=test/L=test/O=test/OU=test/CN=Server CA/emailAddress=test@123.com" -new -x509 -days 3650 -key ca.key -out ca.crt
# 3.生成需要颁发证书的私钥
$ openssl genrsa -out server.key 2048
# 4.生成要颁发证书的证书签名请求,证书签名请求当中的 Common Name 必须区别于 CA 的证书里面的 Common Name
$ openssl req -subj "/C=CN/ST=test/L=test/O=test/OU=test/CN=域名orIP/emailAddress=test@123.com" -new -key server.key -out server.csr
# 5.用 2 创建的 CA 证书给 4 生成的 签名请求 进行签名
$ openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
(参考地址:https://www.cnblogs.com/happy-8090/articles/11830636.html)
从PFX提取到 cert.pem,private.key 两个文件后,可以配置在Nginx里。
另外:
IOS证书: .cer格式,二进制编码
Android证书: .crt格式,base64编码
//TODO 待补充
(1)生成原始RSA私钥文件 rsa_private_key.pem(原始私钥)
openssl genrsa -out rsa_private_key.pem 2048
(2)将原始RSA私钥转换为pkcs8格式private_key.pem(私钥)
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem
(3)生成RSA公钥 rsa_public_key.pem(公钥)
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
curl -vv https://trade8.sctrade.com:10002 -I
curl -vvv https://trade8.sctrade.com:10002 -I