数字签名
# 数字签名
数字签名:RSA 算法的应用
# 什么是数字签名
我们使用非对称加密算法的时候,对于一个公钥-私钥对,通常是用公钥加密,私钥解密。
如果使用私钥加密,公钥解密是否可行呢?实际上是完全可行的。
不过我们再仔细想一想,私钥是保密的,而公钥是公开的,用私钥加密,那相当于所有人都可以用公钥解密。这个加密有什么意义?
这个加密的意义在于,如果小明用自己的私钥加密了一条消息,比如 小明喜欢小红
,然后他公开了加密消息,由于任何人都可以用小明的公钥解密,从而使得任何人都可以确认 小明喜欢小红
这条消息肯定是小明发出的,其他人不能伪造这个消息,小明也不能抵赖这条消息不是自己写的。
因此,私钥加密得到的密文实际上就是数字签名,要验证这个签名是否正确,只能用私钥持有者的公钥进行解密验证。使用数字签名的目的是为了确认某个信息确实是由某个发送方发送的,任何人都不可能伪造消息,并且,发送方也不能抵赖。
# 数字签名举例
为了更好地理解数字签名的作用,我们举个例子来演示数字签名的作用。
# 使用数字签名
首先,鲍勃有两把钥匙,一把是公钥,另一把是私钥。
然后,鲍勃把公钥送给他的朋友们----帕蒂、道格、苏珊----每人一把。
苏珊要给鲍勃写一封保密的信。她写完后用鲍勃的公钥加密,就可以达到保密的效果。
鲍勃收信后,用私钥解密,就看到了信件内容。这里要强调的是,只要鲍勃的私钥不泄露,这封信就是安全的,即使落在别人手里,也无法解密。
鲍勃给苏珊回信,决定采用"数字签名"。他写完后先用 Hash 函数,生成信件的摘要(digest)。
然后,鲍勃使用私钥,对这个摘要加密,生成"数字签名"(signature)。
鲍勃将这个签名,附在信件下面,一起发给苏珊。
苏珊收信后,取下数字签名,用鲍勃的公钥解密,得到信件的摘要。由此证明,这封信确实是鲍勃发出的。
苏珊再对信件本身使用 Hash 函数,将得到的结果,与上一步得到的摘要进行对比。如果两者一致,就证明这封信未被修改过。
# 如果公钥被替换
考虑一个复杂一点的情况,还是中间人攻击问题:
道格想欺骗苏珊,他偷偷使用了苏珊的电脑,用自己的公钥换走了鲍勃的公钥。此时,苏珊实际拥有的是道格的公钥,但是还以为这是鲍勃的公钥。因此,道格就可以冒充鲍勃,用自己的私钥做成"数字签名",写信给苏珊,让苏珊用假的鲍勃公钥进行解密。
此时,苏珊用道格的公钥解密,是能正常解密的。苏珊无法判断公钥到底是否属于鲍勃的!此时,我们就得引入一个可信赖的第三方。
# CA
CA,全称 certificate authority,也就是证书中心,我们认为,这个机构的证书是可信的,并且我们电脑里本身就预装了 CA 的公钥。
鲍勃为了验证自己的身份,可以去找 CA;CA 用自己的私钥,给鲍勃的公钥和一些相关信息(例如所有者是谁)加密,生成的东西叫做数字证书(Digital Certificate)。
鲍勃拿到数字证书后就可以放行了,以后给苏珊写信,就可以附上数字证书了。
苏珊收信后,用 CA 的公钥解开数字证书,就可以拿到鲍勃真实的公钥了,然后就能证明"数字签名"是否真的是鲍勃签的。
# 信任链
我们很难直接向 CA 去申请一个数字证书,因为全世界那么多的机构和人,每个人都去找 CA 的话,CA 根本不可能忙得过来的,并且频繁的使用私钥签名的话,还有可能导致私钥泄漏,这会导致更大的灾难。那怎么办呢?实际操作中,我们可以基于 CA 来构建一个信任链。具体来说,步骤是这样:
- 首先我们的手机、笔记本等操作系统中都预装了 CA 颁发的根证书,他们是所有信任构建的基石
- 然后 CA 找几个机构,让这些机构生成公钥,然后给他们签发数字证书,也就是用 CA 自己的私钥加密了一段话,机构 A,机构 B,机构 C... 是可信的,授权给他们签发数字证书的权利。
- 至此,就可以由机构 A 帮我们签发证书了!机构 A 将他的数字证书发给我们后,我们可以用 CA 的公钥去检查这个数字证书的有效性,如果确实是 CA 签发的数字证书,那么我们就可以信任机构 A,然后就可以找他们签发数字证书了。
- 相同的道理,机构 A 也可以找几个机构授权,继续签发 C 证书,C 继续签发 D 证书................这样就形成了一个信任链
举个生活中的例子:你爸爸绝对相信你是好人,然后你再证明你的朋友 A 是好人,于是你爸爸相信 A 也是好人。
# HTTPS 协议
我们来看个使用数字证书的例子:HTTPS 协议。我们先介绍下 HTTP 协议。
# HTTP 协议
HTTP 协议是超文本传输协议(Hyper Text Transfer Protocol)的缩写,它是从 WEB 服务器传输超文本标记语言 HTML 到本地浏览器的传送协议。HTTP 设计之初是为了提供一种发布和接收 HTML 页面的方法,时至今日,它的作用已经不仅仅于此了。
对于我们 Java 工程师而言,HTTP 应该算是再熟悉不过的东西了,目前 HTTP 有多个版本,使用较多的是 HTTP/1.1 版本。
然而 HTTP 协议有一个缺陷那就是它是通过明文传输数据的(密码、账号、交易记录等机密信息),用户通过 HTTP 协议传输的内容很容易被恶意拦截,并且黑客可以伪装成服务端,向用户传送错误的信息,并且能轻易获取用户的隐私信息,而这些操作用户是完全无感知的。
由于存在这样的安全隐患,现在小伙伴们见到的大部分网站都在逐步转为 HTTPS,HTTP 网站会越来越少了。
HTTPS 全称 Hypertext Transfer Protocol Secure,常称为 HTTP over TLS,HTTP over SSL 或 HTTP Secure,翻译过来就是超文本传输安全协议,是一种网络安全传输协议。关于 TLS 和 SSL 我们后续再介绍
# HTTPS 协议加密过程
HTTPS(HyperText Transfer Protocol Secure)中文译作超文本传输安全协议,这是一种通过计算机网络进行安全通讯的传输协议。加密过程如下:
首先,客户端向服务器发出加密请求。
服务器用自己的私钥加密网页以后,连同本身的数字证书,一起发送给客户端。
客户端(浏览器)的"证书管理器",有"受信任的根证书颁发机构"列表。客户端会根据这张列表,查看解开数字证书的公钥是否在列表之内。
如果数字证书记载的网址,与你正在浏览的网址不一致,就说明这张证书可能被冒用,浏览器会发出警告。
如果这张数字证书不是由受信任的机构颁发的,浏览器会发出另一种警告。
如果数字证书是可靠的,客户端就可以使用证书中的服务器公钥,对信息进行加密,然后与服务器交换加密信息。
# 查看数字证书的内容
我们可以查看一个网站的证书内容,以百度为例:
首先打开百度的网站:百度一下,你就知道 (opens new window)
然后点击 URL 中的锁图标,再点击“连接是安全”的详细信息
再点击“证书有效”,查看证书的完整信息:
然后就可以看到这个证书的信息了,例如属于哪个机构,颁发者是哪个组织,证书有效期等。
目前,浏览器内置了安全机制,实时查验证书状态,通过浏览器向用户展示网站认证信息,让用户轻松识别网站真实身份,防止钓鱼网站仿冒。证书状态正常的网站, 会在网页 URL 上显示一个锁图标:
# 自制证书
如果申请不到数字证书怎么办呢?可以自制证书,并将其发给需要用的客户。在互联网初期,HTTPS 还没有那么普及,12306 就是没有拿到 CA 申请的证书的,因此当时访问的时候会提示
即使不安装证书,强行访问,功能也是用不了的,因为不安全:
为此,我们可以手动安装证书,然后安装它,这样就可以通过 HTTPS 的方式去访问 12306 网站了。
注意,安装证书是一个非常危险的动作!因为安装后,我们就相当于信任了这个机构,如果这个机构后续给几个钓鱼网站颁发了证书,而我们又信任它,那么就很容易被骗。
而我们为什么安装了 12306 网站提供的根证书?是基于对 12306 网站的信任。这个根证书是网站自身提供的,但是我们从新闻联播里,从大众行为里,信任了这个网站,安装了根证书。
安装了 SRCA 的根证书之后,然后访问 http://12306.cn,就没有警告信息了:
一般来说,自制证书,而不是找 CA 机构,都是不受信任的,也不推荐这样做。
# 参考
数字签名是什么? - 阮一峰的网络日志 (opens new window)