数字签名

数字签名可以解决数据安全里面的完整性身份认证不可否认三大特性,但是解决不了机密性问题。机密性需要通过对称密钥 / 公私钥解决,所以数字签名其实和加解密 / 密文 / 机密性这些在概念上非一个层次。
签名的本质不在于加解密,而是加验签。
数字签名,定义上是拿着私钥的一方,通过私钥 X 对消息 M 进行加密 (加签),生成签名 N,并把消息 M 和签名 N 一起给出去。拿着公钥的一方,用公钥 Y 对签名 N 进行解密 (验签) 生成 M’。用消息 M 和 M’ 做比较,如果相等,则数据没有被篡改。如果不想等,则数据不再安全
对于公私钥,我们一般是使用公钥加密私钥解密,这样可以保障单向数据机密性。而私钥加密公钥解密是解决不了机密性问题的,如果要通过公私钥完全解决数据机密性,则需要双向认证。
数字签名就使用了私钥加密公钥解密这套方案,所以数字签名是没有密文 / 机密性可言的。在数据签名里,一般把私钥加密叫做加签,公钥解密叫做验签

对称场景下摘要保障完整性

摘要和摘要算法就不解释了。摘要可以保障完整性,说的是对称加密场景下。
这里有一个疑问点,那就是对称加密场景下,数据本身已经安全了 (机密性)。即中间人无法解开信息,也就无法更改内容。这时候为什么还需要保障完整性?
这里说的对称加密,是排除密钥不安全的场景的。我们已经确定双方持有的对称密钥一定是安全的。这时候黑客虽然拿不到会话密钥,无法破解密文,但可以通过窃听收集到足够多的密文,再尝试着修改、重组后发给服务端。因为没有完整性保证,服务端会 “照单全收”,然后黑客就可以通过服务端的响应获取进一步的线索,最终就会破解出明文。
如果对称加密算法足够安全、对称密钥足够长、使用一次性对称密钥减少通信密文的数量,这些都可以进一步增加破解明文的时间。
但如果因为一些原因,没有上面的安全性保障,就有可能让黑客拿到足够多的样本,增加风险。这时候可以通过摘要来保障密文的篡改:

有了摘要保障完整性,服务端拿到数据后就可以校验一下,不符合完整性要求就可以直接拒绝服务了。
从这里可以看到,摘要就是原数据小且精确的数据替身。通过这个替身只能做到数据完整性校验,对于身份认证这些就做不了了。
实际上单纯在对称场景下,是无法保障数据安全的。因为最多只能做到机密性和完整性,而无法确定密钥的有效性,即身份认证和不可否认。

非对称场景下的摘要和数字签名

开头我们说到了数字签名的定义,从定义上可以看到,数字签名不依赖摘要。前面说到摘要是原数据小且精确的替身,既然是替身,那么数字签名就可以直接操作原数据避开摘要。
因为非对称加密的性能原因,公私钥对大数据的加解密是非常耗时的。有些数据可能达到几百 M 或者几个 G,用公私钥对这些原数据操作的代价是非常大的。
所以数字签名一般不直接对原数据进行加验签,而是通过摘要实现。数据签名并不一定非要使用摘要,但是一般都使用摘要。

1
2
3
性能原因主要发生在原数据过大的场景:
1. 私钥加签耗时严重
2. 签名过大,增加传输时间和流量,验签的相等性依靠字符串匹配算法,也会增加耗时。

数字签名流程如下:

和对称场景下的密文 / 机密性 / 完整性不同,数据签名只用于非对称场景下的明文数据。即:
1.(完整性)我给了你一份明文数据,这份数据虽然大家都可以看到,但我通过数据签名可以保障给你的数据一定是完整的,不会被其他人修改里面的内容,篡改了内容你肯定验签失败。
2.(身份认证)我还可以保障给你的这份数据一定是我给你的,因为你用我的公钥解开了数据,如果不是我亲自用私钥加签,你那边不可能解开数据,验签肯定失败。
3. (不可否认)而且以后我也否认不了本次交易的事实。因为基于完整性和身份认证两个前提,你拿到的数据一定是我亲自给你的有效数据。我无法否认本次交易的数据内容和本次交易的存在事实。

完成这套机制的核心就在于,私钥是非公开的。因为私钥的绝对安全和单一持有,保障了加签人和加签数据的唯一性。

这里说数据签名用于明文场景,是因为数据签名定义上,就是使用私钥进行加签。但加签的数据可以被所有公钥验签后获取,所以没有私密性可言。这也符合非对称加密的特点,即单向安全。数据签名正好使用的是反向,自然就没有密文一说了。
非对称加密只有在公钥加密私钥解密情况下才是安全的,这就是单向认证。如果希望双方的数据都是安全的,就需要使用双向认证了。

数字签名应用场景:PassKey

天下苦 登陆 & 验证码 久矣。
passkey 无密码登陆,是相当期待的功能。目前 Google 平台已经全面上线,Apple 和 微软 都已经对 passkey 做了支持。
无密码登陆,就是通过在终端如 iPhone/Android/Mac/Window 上,建立一份公私钥。
注册的时候,将终端私钥上传到服务端。
登陆的时候,服务端给一个校验字符串,让终端来加签。最后服务端用当初的公钥来解签。能解开并且和校验字符串一致,则表示当前用户值得信任。

https://www.passkeys.io/ 已经做了 passkey 注册的 demo,我体验了一遍,效果很棒。部分流程如下:

图中,是通过 iPhone 终端登录的。其实也可以通过 Mac 端直接登录,这样就可以少了换端的成本。
当通过其他端同步的时候,其实 chrome 浏览器是通过开启一个 socket 通道,使用中继服务器完成 passkey 的获取。

这里其实还有两个问题可以解答:

  1. 终端的公私钥,该怎么保存?这里 iPhone 会通过端侧加密和 iCloud 同步的方案,在 Apple 生态的机子上共享。还可以分享给他人。Android 等终端也都有差不多的能力。
  2. 终端如何确保不是他人来申请 passkey 能力?这里一般通过指纹和面部识别,也可以通过其他硬件辅助验证。

下面是整套 passkey 注册和登录的流程图:

数字签名应用场景:SSL

在 7 层网络协议里,SSL 分为握手协议和记录协议,分别处于表示层和会话层,主要负责网络数据的传输安全。
从对称场景下的摘要可以知道,对称场景下是没有身份认证的,这样就会使得密钥存疑。如果 A 和 B 通信的密钥被 C 给更换了,那么 C 就可以假冒 B 与 A 通信。所以 HTTP 退出了历史舞台。
非对称加密的双向认证是可以解决这个问题,但因为非对称加密耗时厉害,没有被有效的采用。所以就有了通过数字签名来传输公钥,通过单向安全性把临时对称密钥给到对方,而后双方使用对称密钥通信的策略。这就是 HTTPS (SSL/TSL) 使用的方案。
SSL/TSL 本身还是复杂的,上面只是简化流程,表达数字签名的用途

HTTPS 的安全核心在于对称密钥 (或者种子) 的安全传输。根据非对称加密单向安全性,只要拥有公钥的一方生成对称密钥并把密钥通过公钥加密给到另一方,拥有私钥的对方才可以解开数据并拿到密钥,这样就安全传输了。
而数据签名之所以能传递有效的公钥,就是因为它具有完整性、身份认证、不可否认的特点。拿到的公钥,一定是安全的公钥,如果被动了手脚,一定会被发现。

数字签名应用场景:SSH

SSH 全称 Secure Shell,即 “安全壳协议 “。SSH 突破安全枷锁的方式和 SSL 是一样的,相比来说少了证书链校验这个环节,即 Client 和 Service 需要自行保障公钥的可靠。
具体来说很直接,就是如果 Client 需要登陆 Service,第一次登陆的时候 SSH 工具会提示 Service 的公钥,人们需要看下这个公钥和 Service 那边公开的公钥是否一致。一致后 Client 侧会做公钥缓存,后面就不会再提示了。
其他的都和 HTTPS 是一样的了,通过公私钥确认对称密钥,通过对称密钥进行数据安全传输。

数字签名应用场景:iPhone App

iPhone 的 ipa 包,有非常多的安装限制,都是通过数字签名来控制的。Apple 使用的双重认证方案,即开发者和 Apple 公司同时提供公私钥签名,来使得 ipa 包不会被滥用和滥安装。

总结

数字签名是通过私钥加签,所有公钥都能验签,所以没有机密性可言。数字签名实现了完整性身份认证不可否认,而机密性则是通过对称加密 / 非对称加密来完成密文保障。
数字签名,是数据安全的基石。