你是否经常像我一样对于 SSL 数字证书的各种编码格式和扩展名诸如 .pem、.der、.crt、.cer、.csr、.p12、X.509 等表示很困惑,这篇文章将告诉你答案。
我们知道,在 HTTPS(HTTP over SSL)请求的 SSL 握手阶段,服务端以数字证书的方式将 RSA 公钥传给客户端,以保证公钥在传输过程中不被篡改,而公钥将用于加密后续数据传输对称加密的密钥(以后再细讲这一过程)。
SSL 数字证书的主要目的是 用于传递服务端公钥 ,我们下面来了解一下证书的标准、编码格式以及常见的文件扩展名。
字段 | 说明 |
---|---|
Suject Name | 证书持有者的相关信息(国家/地区、组织、单位、CN) |
Issuer Name | 证书颁发者的相关信息(国家/地区、组织、单位、CN) |
Common Name | Subject Name 和 Issuer Name 信息里都包含一个常用名称字段(Common Name, CN),对于 CA 证书而言,该字段表示 CA 机构的名称, 对于用户证书而言,通常是相应的域名。 |
Serial Number | CA 机构给该证书的唯一序列号 |
Not Valid Before | 证书生效日期 |
Not Valid After | 证书失效日期 |
Public Key | 服务端公开的密钥(RSA 公钥) |
Signature Algorithm | 签名所使用的算法(SHA-1,SHA-256 等) |
Signature | CA 机构给该证书的签名,用于验证证书是否被篡改 |
下图就是我个人博客 kangzubin.cn
域名下的数字证书,可通过 Chrome 浏览器查看其详细内容。
X.509 标准的证书文件具有不同的编码格式,一般包括 PEM
和 DER
两种。
-----BEGIN XXX-----
,并以 -----END XXX-----
结尾,中间 Body 内容为 Base64 编码过的数据。 例如,以 PEM 格式存储的证书结构大概如下:
-----BEGIN CERTIFICATE----- Base64编码过的证书数据 -----END CERTIFICATE-----
通过如下 OpenSSL 命令可以查看其证书内容:
openssl x509 -in xxx.pem -text -noout
它也可以用来编码存储公钥(RSA PUBLIC KEY)、私钥(RSA PRIVATE KEY)、证书签名请求(CERTIFICATE REQUEST)等数据。
一般 Apache 和 Nginx 服务器应用偏向于使用 PEM
这种编码格式。
openssl x509 -in xxx.der -inform der -text -noout
一般 Java 和 Windows 服务器应用偏向于使用 DER
这种编码格式。
当然同一 X.509 证书的不同编码之间可以互相转换:
openssl x509 -in xxx.pem -outform der -out xxx.der
openssl x509 -in xxx.der -inform der -outform pem -out xxx.pem
证书文件扩展名是比较误导人的地方,我之前也一直没搞明白!
如上所述,对于 X.509 标准的证书两种不同编码格式,一般采用 PEM
编码就以 .pem
作为文件扩展名,若采用 DER
编码,就应以 .der
作为扩展名。但常见的证书扩展名还包括 .crt
、 .cer
、 .p12
等,他们采用的编码格式可能不同,内容也有所差别,但大多数都能互相转换,现总结如下:
PEM
编码格式的 X.509 证书的文件扩展名; DER
编码格式的 X.509 证书的文件扩展名; PEM
编码,也有可能是 DER
编码, 但绝大多数情况下此格式证书都是采用 PEM
编码 ; PEM
编码,也可能是 DER
编码, 但绝大多数情况下此格式证书都是采用 DER
编码 ; .csr
申请的时候,同时也会生成一个配对 RSA 私钥,私钥通常需要严格保存于服务端,不能外泄。 PEM
,也可能是 DER
,查看方式如下: PEM 编码格式:openssl rsa -in xxx.key -text -noout DER 编码格式:openssl rsa -in xxx.key -text -noout -inform der
以上。
在下一篇博文,我将详细地介绍 iOS 开发中遇到的 HTTPS、SSL/TLS 握手、RSA 加密/解密、数字证书的 CA 签发与校验过程、中间人攻击、SSL Pinning 与 HTTPS 双向验证等技术的概念与实现。