SSL/TLS数字证书各种格式解释
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提取 证书和秘钥:
#.pfx 生成 加密秘钥:
openssl pkcs12 -in server.pfx -nocerts -out encrypt_pri_key.pem //输入pfx密码后,需要再输入 PEM pass phrase
#输出数据内容:
BEGIN ENCRYPTED PRIVATE KEY
#.pfx 生成 秘钥(未加密的):
openssl pkcs12 -in server.pfx -nocerts -nodes -out encrypt_pri_key.pem //输入pfx密码即可
#输出数据内容:
BEGIN PRIVATE KEY
#.pfx 生成 客户端证书:
openssl pkcs12 -in server.pfx -clcerts -nokeys -out cert.pem //输入pfx密码即可
#输出数据内容:
BEGIN CERTIFICATE
#.pfx 生成 客户端证书+加密秘钥:
openssl pkcs12 -in server.pfx -clcerts (-nodes 同上) -out cert_and_en_pri_key.pem //有证书和加密秘钥
#输出数据内容:
BEGIN CERTIFICATE
BEGIN ENCRYPTED PRIVATE KEY
#加密秘钥 生成 RSA私钥:
openssl rsa -in encrypt_pri_key.pem -out private.key //需要输入 pass phrase
#输出数据内容:
RSA PRIVATE KEY
#客户端证书以 der 编码生成 .crt 证书
openssl x509 -outform der -in cert.pem -out crt.crt
#输出数据内容:
二进制数据
PEM编码的证书签名请求文件: BEGIN CERTIFICATE REQUEST
3、合成 .pfx
openssl pkcs12 -export -out server.pfx -inkey pair.key -in crt.crt //unable to load certificates
openssl pkcs12 -export -out server.pfx -inkey public.key -in crt.crt //unable to load private key
openssl pkcs12 -export -out server.pfx -inkey private.key -in crt.crt //unable to load certificates
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
openssl pkcs12 -export -out server.pfx -inkey pair.key -in encrypt_pri_key.pem //unable to load certificates
openssl pkcs12 -export -out server.pfx -inkey private.key -in encrypt_pri_key.pem //unable to load certificates
提示输入 .key文件的密码
提示输入即将生成的 .pfx文件的密码(需要输入两次)
若成功,会生成 server.pfx文件
4、另一种提取私钥的方法,从公钥对中提取:
从pfx证书中提取密钥信息,并转换为key格式(pfx使用pkcs12模式补足) 1、提取密钥对(如果pfx证书已加密,会提示输入密码) openssl pkcs12 -in server.pfx -nocerts -nodes -out pair.key BEGIN PRIVATE KEY //1,和 4 相同,但比 4 多一些 Attributes 2、从密钥对提取公钥 openssl -in pair.key -pubout -out public.key BEGIN PUBLIC KEY //或者 //openssl rsa -in encrypt_pri_key.pem -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)
从PFX提取到 cert.pem,private.key 两个文件后,可以配置在Nginx里。
另外:
IOS证书: .cer格式,二进制编码
Android证书: .crt格式,base64编码