本文主要介绍数字签名(digital signature)技术的相关知识。
1 概述
1.1 What
数字签名(又称公钥数字签名、电子签章),是一种类似写在纸上的、普通的物理签名,只不过数字签名通过公钥加密领域的技术实现。数字签名属于鉴别数字信息的方法。一套数字签名通常定义两种互补的运算:一个运算用于签名,另一个运算用于验证签名(验签)。
数字签名,就是只有信息的发送者才能产生的、别人无法伪造的一段数字串,这段数字串是对信息发送者所发送信息真实性的一个有效证明。
数字签名是非对称密钥加密技术与数字摘要技术的应用。
数字签名文件的完整性是很容易验证的(不需要骑缝章、骑缝签名,也不需要笔迹专家),而且数字签名具有不可抵赖性(不需要笔迹专家来验证)。
简单地说,所谓数字签名,就是附加在数据单元上的一些数据,或者是对数据单元所做的密码变换,通过使用这些数据或变换,数据单元的接收者能够确认数据单元的来源、数据单元的完整性,并且(这些数据或变换)保护数据、防止被人(例如接收者)进行伪造。
数字签名是对电子形式的消息进行签名的一种方法,一个签名消息能在通信网络中传输。
尽管基于公钥密码体制和私钥密码体制都可以获得数字签名,不过目前主要是基于公钥密码体制的数字签名。
1.2 应用场景
数字签名技术的应用场景较多,在此介绍一种常见的应用场景。
通过使用数字签名技术,将摘要信息(数字摘要是将任意长度的消息变成固定长度的短消息,这里描述的是对原文使用HASH函数生成的一个摘要信息)使用发送者的私钥加密,与原文一起发送给接收者。接收者通过发送者的公钥解开被加密的摘要信息,同时使用HASH函数对收到的原文生成一个摘要信息,然后对比这两份摘要信息:如果对比结果相同,则说明收到的信息是完整的,即信息在传输过程中没有被修改;否则,说明信息被修改过。这就是通过数字签名技术验证信息的完整性的典型应用场景。
数字签名是个加密的过程,数字签名验证(验签)是个解密的过程。
1.3 作用
数字签名的作用是:保证信息传输的完整性、进行信息发送者的身份认证、防止交易中的抵赖发生。
2 示例
继承另一篇非对称加密算法文章:为了确保通信中的一方得到的公钥K2确实是通信另一方发布的公钥K2(而不是中间人mim伪造的公钥K2),数字签名技术应运而生。
下面通过示例演示,介绍数字签名的相关知识。
2.1 使用数字签名生成CRT
生成CRT(CA signed certificate)的过程如下:
1. 小红把自己的公钥K2和ID(身份证号码,或者域名)合成为身份证申请(certificate signing request, CSR),如下:
小红的CSR = 小红公钥K2 + 小红域名
2. 小红把自己的CSR发给一个德高望重的人(称为CA,即certificate authority),比如小亮;
3. 小亮用自己的私钥K1加密小红的CSR,得到的密文被称为数字签名(digital signature,下面简称signature),如下:
小亮的signature = E(小红的CSR, 小亮的私钥K1)
4. 小亮把signature和小红的CSR的明文合在一起,称作经过CA签署的身份证(CA signed certificate, CRT),发给小红,成为了小红的CRT,如下:
小红的CRT = 小红的CSR + 小亮的signature
说明:单纯的CSR都是明文的,因为CSR只是公钥和ID的组合。
2.2 根据数字签名进行认证
在上面生成了小红的CRT后,如果小明要与小红聊天,过程如下:
1. 小明想要与小红聊天(建立HTTPS连接)时,小红出示了自己的CRT,该CRT是经过小亮(CA)签署的;
2. 小明拿到了小红的CRT后,看到了这个CRT是经过小亮签署的,因为小亮很权威,小明是相信小亮的(小明预先在自己的机器上安装了小亮的身份证CRT。这里小亮的身份证CRT是小亮对外公布的,其实是一个自签名的CRT);
3. 小明从小亮的身份证CRT中获取小亮的CSR,再从小亮的CSR中提取小亮的公钥K2。如下:
小亮的公钥K2 = 小亮的CRT中的CSR(明文)中的公钥K2
4. 小明用提取的小亮的公钥K2,解密小红CRT中小亮的signature,得到了小红的CSR'。如下:
小红的CSR' = D(CRT中小亮的signature, 小亮的公钥K2)
5. 如果第4步中得到的这个小红的CSR'和小红CRT中的CSR(明文)一致,则说明“这个小红的CRT是经过小亮确认过并且签名的,所以这个小红的CRT是可信的”。如下:
if 小红的CSR' == 小红的CRT中的小红的CSR(明文)
小红的CRT可信
6. 所以,既然小红的CRT是可信的,小明就可以获取小红CRT中的CSR中的小红的公钥K2,进行后续通信了。
2.3 Who is CA
从上述过程中可以看出,任何人或机构都可以作为CA,只要他愿意公开自己的公钥K2(通过自签名、提供自己的CRT的方式),那么他就可以用自己的私钥去加密别人的CSR(从而生成signature),签署生成别人的CRT。
如果CA不可靠,那就没有办法了,很多操作系统(Windows、Mac OS X)和浏览器(Chrome、Firefox、IE)会内置一些可靠的CA的身份证,我们可以从这些可靠的CA的身份证中获取该CA的公钥K2,如果后面遇到了该CA签署的别人的身份证,那么就可以通过该CA的公钥K2验证那个人的身份证是否可信了。
2.4 信任链
在上文中,CA小亮如果担心没人相信自己是个权威的CA,那么可以找一个大家都相信的CA(比如老王),然后让老王对小亮的CRT进行签名,如下:
小亮的CSR = 小亮的公钥K2 + 小亮的域名
老王的signature = E(小亮的CSR, 老王的私钥K1)
小亮的CRT = 小亮的CSR(明文) + 老王的signature
经过上述步骤后,如果浏览器或者操作系统中安装了老王的身份证CRT,那么我们就可以从中获取老王的公钥K2,从而验证“小亮的身份证CRT是老王确认并且签名过的”。
此时,小亮在签署小红的CRT时,可以在小红的CRT后面附上小亮的CRT,这样小红的CRT就有“两页”了。
当小明和小红通信时,过程如下:
1. 小红出示自己的CRT,该CRT是经过小亮认证的,而小亮的CRT又是经过老王认证的;
2. 小明虽然不信任小亮,但是因为信任老王,所以小明先用老王的公钥K2来验证小红CRT中附带的小亮的CRT;
3. 经过验证,小明信任了小亮;
4. 然后,小明再用小亮的公钥K2来验证小红的CRT;
5. 最终,小明信任了小红。
要是怕小明连自己也不信任,老王可以再找一个小明信任的人来签名自己的身份证。这个过程可以不断递推,从而形成一条信任链(trust of chain)。
2.5 根CA和自签名
前面介绍了信任链,不过信任链总会有个顶端,即最后一个签名者(CA),这个最后的签名者被称为根CA(root CA)。
根CA对应的CRT称为根身份证,根身份证是由根CA自己签名的。
实际上,我们每个人都可以自己签名认证自己的身份证,得到自签名的身份证(self-signed certificate)。生成自签名身份证的过程如下:
- 生成一对秘钥:公钥K2和私钥K1;
- 创建自己的CSR;
- 用自己的秘钥K1加密CSR,得到signature;
- 最后,把自己的CSR(明文)和signature一起发布,生成自己的CRT。
任何人,只要相信我们的自签名CRT,就可以用我们的CRT中的CSR中的公钥K2加密传送给我们的信息,然后我们就可以通过私钥K1来解密。
在2.4节的示例中,如果老王是根CA,那么身份证信任链如下:
【小红的CRT】
小红的CSR = 小红公钥K2 + 小红域名
小亮的signature = E(小红的CSR, 小亮的私钥K1)
小红的CRT = 小红的CSR(明文) + 小亮的signature
【小亮的CRT】
小亮的CSR = 小亮的公钥K2 + 小亮域名
老王的signature = E(小亮的CSR, 老王的私钥K1)
小亮的CRT = 小亮的CSR(明文) + 老王的signature
【老王的CRT】
老王的CSR = 老王的公钥K2 + 老王的域名
老王的signature = E(老王的CSR, 老王自己的私钥K1) --- 根CA,自签名
老王的CRT = 老王的CSR(明文) + 老王的signature