1.10 数字证书
数字证书是一种权威的电子证明,由权威公正的第三方证书颁发机构(CA)签发,用来证明公钥拥有者的身份。数字证书中包含了公钥信息、拥有者身份信息,以及CA对这份文件的数字签名,用以保证这份文件的整体内容正确无误。数字证书被广泛用于需要身份验证和数据安全的领域,简单来说就是数字证书能够证明这个公钥被谁拥有。数字证书主要用来保证信息保密、身份确认、不可否认性和数据完整性,常见的格式是X.509格式。
用户想要获得数字证书,应该先向CA提出申请,CA验证申请者的身份后,为其分配一个公钥并且与其身份信息绑定。CA为该信息进行签名,作为数字证书的一部分,然后把整个数字证书发送给申请者。
当需要鉴别数字证书的真伪时,只需要用CA的公钥对数字证书上的签名进行验证即可,验证通过则证明数字证书有效。
1.10.1 数字证书结构
数字证书的结构一般采用X.509格式,X.509格式使用ASN.1(Abstract Syntax Notation One)抽象语法标记来表示。ASN.1是一种由国际标准组织(ISO/ITU-T)制定的标准,描述了一种对数据进行表示、编码、传输和解码的数据格式,用于实现平台之间的互操作性。X.509格式的数字证书结构如图1-4所示。
图1-4 X.509格式的数字证书结构
在X.509格式的数字证书中,各个字段含义如下。
• 版本:数字证书使用X.509规范的版本,目前普遍使用v3版本。
• 序列号:CA会为每个颁发的数字证书分配一个整数,作为数字证书的唯一标识。
• 签名算法:CA颁发数字证书使用的签名算法。
• 有效期:包含数字证书的起止日期。
• 主体名:该数字证书拥有者的名称,如果与颁发者相同,则说明该数字证书是一个自签名证书。
• 公钥信息:对外公开的公钥及所使用的公钥生成算法。
• 扩展信息:通常包含数字证书的用法、证书吊销列表(Certificate Revocation List,CRL)的发布地址等可选字段。
• 签名:颁发者用私钥对数字证书信息的签名。
前文提到TLS协议已经广泛地应用于浏览器中,我们在对网站进行浏览时,可以发现很多网站都采用HTTPS协议来提供对网站服务器的身份验证。HTTPS协议经由HTTP进行通信,但利用SSL/TLS协议来加密数据包。我们可以通过找到采用HTTPS协议的网站查看网站证书来加深对数字证书的理解,图1-5查看了Google网站的数字证书。
图1-5 通过浏览器查看数字证书
1.10.2 数字证书类型
数字证书根据用途的不同,有不同的分类。
自签名证书:自签名证书又称根证书,是CA颁发给自己的证书,证书的颁发者和主体同名,也就意味着证书中的公钥和用于验证证书的密钥是相同的。自签名证书通常不会被广泛信任,使用时可能会遇到系统软件的安全警告。
如果软件安装自签名证书则意味着对这个CA的信任,通常而言,自签名证书已预先安装在各种软件(包括操作系统、浏览器、电邮软件等)中,作为信任链的起点。自签名证书一般来自公认可靠的政府机关、软件公司(如Google、Let's Encrypt)、证书颁发机构公司(如VeriSign)等,各大软件商通过严谨的核认程序才可以在不同的软件中部署自签名证书。由于部署程序复杂、费时,需要行政人员的授权及机构法人身份的核认,一经部署,自签名证书有效期可能长达10年以上。某些企业可能会在内部计算机自行安装企业自签的自签名证书,以支持内部网的企业级软件,但是这些证书可能未被广泛认可,只在企业内部适用。
中介证书:CA的一个重要任务是为客户签发证书,虽然广泛认可的CA都已拥有自签名证书,相对应的私钥可以用来签署其他证书,但因为密钥管理和行政考虑,一般会先行签发中介证书,才为客户进行数字签署。中介证书的有效期比自签名证书短,并可能对不同类别的客户进行不同的中介证书分工。
服务器证书:服务器通常以域名形式在互联网上提供服务,服务器证书上主体的通用名称就是相应的域名,相关机构名称则写在组织或单位一栏上。服务器证书(包括公钥)和私钥会安装在服务器(如Apache)上,等待客户端连接时协议加密细节。客户端的软件(如浏览器)会运行认证路径验证算法以确保安全,如果不能肯定加密通道是否安全(如证书上的主体名不对应网站域名、服务器使用了自签名证书或加密算法不够强),可能会警告用户。
终端实体证书:不会被用作签发其他证书的证书都可称为终端实体证书。终端实体证书被用来在实际的软件中部署或在创建加密通道时应用。
授权证书:授权证书又称属性证书,本身没有公钥,必须依附在一张有效的数字证书上才有意义,其用处是赋予相关拥有者签发终端实体证书的权利。在某些情况下,如果只在短期内授予CA签发权利,便可以不改变(缩短)该机构本身持有的证书的有效期。这种情况,类似于某人持有长达10年的护照,而只通过签发短期入境签证来个别赋予护照持有人额外权利。
1.10.3 数字证书编码
数字证书在计算机中的表示方法有所不同,但是都是可以相互转换的,常见的编码格式为PKCS#12、DER和PEM。
PKCS标准是指由RSA Security设计和发布的一组公钥加密标准。因此,RSA Security及其研究部门RSA Labs有义务促进公钥技术的使用。为此,他们(从20世纪90年代初开始)开发了PKCS标准,并保留了对PKCS标准的控制权,宣布他们会在自己认为必要的时候进行改变或改进,因此,PKCS标准在重要意义上并不是真正的行业标准,尽管名称如此。对于PKCS标准,常见的是标准PKCS#12,其中#12是标准编号,文件后缀是P12。
DER(可分辨编码规则)是一种用于存储X.509证书文件的流行编码标准。ASN.1的可分辨编码规则是根据X.509规范对BER编码的约束得出的国际标准。DER编码是有效的BER编码。DER编码与BER编码相以,只是删除了一个发送者的选项。例如,在BER编码中,布尔值true可以用255种方式编码,而在DER编码中,只有一种方法可以编码布尔值true。DER编码的完整规范在RFC 1421中。
X.509证书文件最常用的编码方案是PEM(隐私增强邮件)编码。PEM编码的完整规范在RFC 1421中。在X.509证书文件上进行PEM编码的想法非常简单:使用Base64编码对内容进行编码。编码后的文件后缀通常为PEM,将Base64编码输出括在两行之间:“----- BEGIN CERTIFICATE -----”和“----- END CERTIFICATE -----”,下面的例子是PEM编码的X.509证书结构示例。
DER编码的X.509证书文件是二进制文件,无法使用文本编辑器查看,但几乎所有应用程序都支持DER编码的证书文件。DER编码的证书文件的文件扩展名为“.cer”“.der”“.crt”。
1.10.4 简单应用
假设一个简单的场景,Alice需要通过银行转给Bob一笔钱,使用之前的密码学知识就可以保证这个过程的安全可靠。
可以通过对称加密的方式,生成公私钥对,其中,公钥a可以公开,作为银行账户;私钥b作为账户密码,不予公开。
当Alice向Bob转100元时,可以在计算机中向银行发送这样一条请求<form:Alice, to:Bob, value: 100>,表示Alice向Bob转账100元。如果整个过程不加验证,被黑客发现这个漏洞后就可以不断地重复这个过程,直到把Alice的账户余额转空。
为了表示这个交易确实是由Alice发出的,可以增加Alice的签名,用Alice的公钥a所对应的私钥对这个请求签名。整个请求就成了{<form:Alice, to:Bob, value: 100>, signature: foo},这样银行收到这笔交易后,就可以用Alice的公钥,也就是a对交易进行验证,判断是不是由Alice发出的。
但是由于Alice太过富有,转账成了{<form:Alice, to:Bob, value: 1000000000.002>, signature: bar},交易请求<form:Alice, to:Bob, value: 1000000000.002>体积太大,签名算法对大量数据的输入签名效率不高,这个时候,就可以采用消息摘要算法,减少计算签名输入的长度的工作量,如首先采用哈希算法计算Hash(<form:Alice, to:Bob, value: 1000000000.002>)=baz,然后对摘要baz签名即可。当银行收到这笔交易时,同样先对交易计算哈希值,再验证签名即可。