>

在进行网络开发时,经常会需要处理加密连接等跟证书加密等相关的概念,本文总结了证书加密等常见的名词术语及文件格式。


术语及常见概念

SSL - Secure Sockets Layer

现在应该叫”TLS”,但由于习惯问题,还有很多场景下会称为”SSL”,涵义跟 TLS 完全相同。我们知道,HTTP 协议默认情况下是不加密内容的,在内容传播的时候由于是明文的容易被人截获。对于安全性要求较高的场合,需要对传输加密才能保证内容不被泄露,HTTPS 就是带加密的 HTTP 协议,它的加密是基于 SSL 加密协议的,这个加密对用户和开发者来说都是透明的,详见维基百科

OpenSSL

简单地说,OpenSSL 是 SSL 的一个实现,SSL只是一种规范。理论上来说,SSL 这种规范是安全的,目前的技术水平很难破解。但SSL的实现就可能有些漏洞,如著名的”心脏出血(Heartbleed bug)“。OpenSSL 提供了一大堆强大的工具软件,强大到 90% 我们都用不到。

ASN.1

Abstract Syntax Notation One,抽象语法标记,一种 ISO/ITU-T 标准,该标准描述了一种对数据进行表示、编码、传输和解码的数据格式。
我们可以把其类比成为开发语言提供的各种基础类型,X.509使用了这些基础类型来定义了数字证书的数据结构。(参考链接:ASN.1

X.509

X.509 是最常见的一种数字证书标准,由国际电信联盟(ITU-T)依据 ASN.1 规范制定,它规定了证书应包含哪些信息和使用什么样的编码格式(默认DER二进制编码)。
其详情可以参考 RFC5280,SSL使用的就是这种证书标准。简单来说,X.509 是使用ASN.1 提供的抽象语法定义了证书的数据结构和编码规范。
同样的 X.509 数字证书,可能有不同的编码格式,目前有以下两种编码格式:

(1)PEM - Privacy Enhanced Mail
最初是为了增强邮件安全,将 X.509 证书用 base64 进行重新编码随着邮件一起传输,现在基本就用来生成公钥/私钥文件供用户下载了,原本的功能反而不再重要。

Openssl 使用 PEM 格式来存放各种信息,是 openssl 默认采用的信息存放方式。
Openssl 中的 PEM 文件一般包含如下信息:

  • 内容类型: 表明本文件存放的是什么信息内容,它的形式为 “——-BEGIN XXXX ——”,与结尾的 “——END XXXX——” 对应。
  • 头信息: 表明数据是如果被处理后存放,openssl 中用的最多的是加密信息,比如加密算法以及初始化向量 iv。
  • 信息体: 为 BASE64 编码的数据。可以包括所有私钥(RSA 和 DSA)、公钥(RSA 和 DSA)和 (x509) 证书。它存储用 Base64 编码后的 DER 格式数据,用 ascii 报头包围,因此适合系统之间的文本模式传输。

(i) 使用PEM格式存储的证书:

—–BEGIN CERTIFICATE—–
MIICJjCCAdCgAwIBAgIBITANBgkqhkiG9w0BAQQFADCBqTELMAkGA1UEBhMCVVMx
...
1p8h5vkHVbMu1frD1UgGnPlOO/K7Ig/KrsU=
—–END CERTIFICATE—–

(ii) 使用PEM格式存储的私钥:

—–BEGIN RSA PRIVATE KEY—–
MIICJjCCAdCgAwIBAgIBITANBgkqhkiG9w0BAQQFADCBqTELMAkGA1UEBhMCVVMx
...
1p8h5vkHVbMu1frD1UgGnPlOO/K7Ig/KrsU=
—–END RSA PRIVATE KEY—–

(iii) 使用PEM格式存储的证书请求文件:

—–BEGIN CERTIFICATE REQUEST—–
MIICJjCCAdCgAwIBAgIBITANBgkqhkiG9w0BAQQFADCBqTELMAkGA1UEBhMCVVMx
...
1p8h5vkHVbMu1frD1UgGnPlOO/K7Ig/KrsU=
—–END CERTIFICATE REQUEST—–

根据上述例子展示的是证书的文本内容,我们可以看到,如果起始行是 –BEGIN CERTIFICATE–,说明这是一个证书
如果是 —–BEGIN RSA PRIVATE KEY—–,就说明这是一个私钥。
文本格式怎么变成二进制?从程序角度来说,去掉前后的—-行,剩下的去掉回车,然后用 base64 解码,就得到二进制了格式的证书了。

我们通过 openssl 来完成这个工作,

(i) 用openssl创建 CA 证书的 RSA 密钥(PEM格式):

$ openssl genrsa -des3 -out ca.key 1024

(ii) 用openssl创建CA证书(PEM格式,假如有效期为一年):

$ openssl req -new -x509 -days 365 -key ca.key -out ca.crt -config openssl.cnf

openssl 是可以生成DER格式的CA证书的,在 Windows 下最好将 PEM 格式的 CA 证书转换成 DER 格式的 CA 证书。

查看PEM格式证书的信息: openssl x509 -in certificate.pem -text -noout

(2)DER - Distinguished Encoding Rules

可包含所有私钥、公钥和证书。它是大多数浏览器的缺省格式,并按 ASN1 DER 格式存储。注意它是无报头的,而 PEM 则是用文本报头包围的 DER。

其他

PKCS

The Public-Key Cryptography Standards,公钥密码学标准。RSA 公司制定的一系列规范,#7/#12对基础X.509证书和证书对应的私钥进行扩充、加密、重新编码后用于交换,#8定义了一种私钥格式标准。
PKCS#7 常用的后缀是:.P7B, .P7C, .SPC,PKCS#12 常用的后缀有:.P12, .PFX


文件扩展名

一般来说上述的两种加密格式分别使用 .pem.der 作为文件名后缀来进行标示。

还有以下常见后缀:

CRT
Certificate的简写,*NIX 系统下常见的证书文件后缀。.crt 后缀的证书文件有可能是 PEM 编码,也有可能是DER编码,大多数是 PEM 编码。

CER
同样是 Certificate 的简写,Windows系统下常见的证书文件类型后缀。.cer 后缀的证书可能是PEM编码,也可能是DER编码,大多数是 DER 编码。

注意:.cer.crt 文件是二进制形式存放的,只放证书,不含私钥。

KEY
通常用来存放一个公钥或者私钥,并非X.509证书,编码类型可能是 PEM 或 DER。
查看 KEY 的办法: openssl rsa -in mykey.key -text -noout
如果是 DER 格式:openssl rsa -in mykey.key -text -noout -inform der

CSR
Certificate Signing Request,证书签名请求。
生成 X509 数字证书前,需要用户向权威证书颁发机构提交证书申请文件,然后由 CA 来签发签名后的证书。
X509 证书申请的格式标准为 pkcs#10 和 rfc2314,大致过程如下:

1. 用户生成自己的公私钥对;
2. 构造自己的证书申请文件,符合 PKCS#10 标准。该文件主要包括了用户信息、公钥以及一些可选的属性信息,并用自己的私钥给该内容签名;
3. 用户将证书申请文件提交给 CA;
4. CA 验证签名,提取用户信息,并加上其他信息(比如颁发者等信息),用 CA 的私钥签发数字证书;

说明:数字证书(如x.509)是将用户(或其他实体)身份与公钥绑定的信息载体。一个合法的数字证书不仅要符合 X509 格式规范,还必须有 CA 的签名。
用户不仅有自己的数字证书,还必须有对应的私钥。
X509v3 数字证书主要包含的内容有:证书版本、证书序列号、签名算法、颁发者信息、有效时间、持有者信息、公钥信息、颁发者 ID、持有者 ID 和扩展项。

其核心内容是一个公钥(还附带了一些别的信息),在生成这个申请的时候,同时也会生成一个私钥,私钥要自己保管好。
查看 CSR 的办法: openssl req -noout -text -in my.csr (如果是DER格式的话照旧加上 -inform der)

PFX/P12
Personal Information Exchange 个人信息交换协议。Predecessor of PKCS#12, 对 *nix 服务器来说,一般 CRT 和 KEY 是分开存放在不同文件中的,但 Windows 下的 IIS 则将它们存在一个 PFX 文件中(因此这个文件同时包含了证书及私钥)。那么这样会不会造成不安全?答案是不会,PFX 通常会有一个”提取密码”,你想把里面的东西读取出来的话,它就要求你提供提取密码,PFX使用的是 DER 编码,那么如何把 PFX 转换为 PEM 编码?

A .pfx file is a PKCS#12 archive, usually containing a certificate and the corresponding private key.
On the other hand, a .cer or .crt file usually contains a single certificate, alone and without any wrapping (no private key, no password protection, just the certificate).

$ openssl pkcs12 -in for-iis.pfx -out for-iis.pem -nodes

这个时候会提示你输入提取代码。提取成功后 for-iis.pem 就是可读的文本.
生成 pfx 的命令类似这样: openssl pkcs12 -export -in certificate.crt -inkey privateKey.key -out certificate.pfx -certfile CACert.crt
其中 CACert.crt 是CA(权威证书颁发机构)的根证书,有的话也通过 -certfile 参数一起带进去。

从 PFX 格式文件中提取私钥格式文件 (.key)

$ openssl pkcs12 -in mycert.pfx -nocerts -nodes -out mycert.key

简单来说,pfx/p12 用于存放个人证书/私钥,其通常包含保护密码,2进制方式存储。

JKS
Java Key Storage,这是 Java 的专利,跟OpenSSL关系不大。利用Java的一个叫”keytool”的工具可以将PFX转为JKS,当然 keytool 也能直接生成JKS。


证书编码的转换

(1) PEM转为DER

$ openssl x509 -in cert.crt -outform der -out cert.der

(2) DER转为PEM

$ openssl x509 -in cert.crt -inform der -outform pem -out cert.pem

(提示:要转换KEY文件也类似,只不过把 x509 换成 rsa,要转CSR的话,把x509换成req…)


获得证书

有两种方式获得证书

(1) 向权威证书颁发机构申请证书

先生成一个 csr 证书请求

$ openssl req -newkey rsa:2048 -new -nodes -keyout my.key -out my.csr

生成 .csr 文件之后,把其交给权威证书颁发机构,权威证书颁发机构将会对改 .csr 文件进行签名。签名返回给用户,当权威证书颁发机构颁发的证书过期的时候,你还可以用同样的csr来申请新的证书,key 可以保持不变。

(2) 生成自签名的证书

$ openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem

在生成证书的过程中会要你填一堆的东西,其实真正要填的只有 Common Name,通常填写你服务器的域名(如”yourcompany.com”),或者你服务器的IP地址,其它项可以默认留空。
生产环境中还是不要使用自签的证书,否则浏览器会不认。或者如果你是企业应用的话能够强制让用户的浏览器接受你的自签证书也行。向权威机构要证书通常是要钱的,但也有一些是免费的,仅仅需要一个简单的域名验证即可。




Reference
http://blog.csdn.net/anxuegang/article/details/6157927
https://www.sslshopper.com/ssl-converter.html