6.824 Lecture 18: Certificate Transparency, Equivocation ,证书透明度(Certificate Transparency)
为什么要研究证书透明度(CT)?
- 迄今为止我们假设的是封闭的系统,所有参与者都是值得信赖的,比如Raft peers
- 要是系统是对外的,任何人都可以使用呢?
- 没有普遍信任的权限检查来运行该系统?
- 你必须在彼此都怀疑的情况,构建可用的系统。
- 这使得信任和安全是分布式系统最上层的问题,
- 最基础的问题“我是否和一台正确的计算机通信?”,这就是CT要解决的问题(大多不可解)
- 这份材料在一致性的基础上:因为CT就是要确保所有参与方都看到同样的信息
- 这份材料偏向区块链和比特币:CT不是类似区块链式设计的非加密货币,而且已经投入工业界,使用广泛
在证书之前(1995之前) 中间人(man-in-the-middle,MITM)攻击是互联网关注的话题
[browser, internet, gmail.com, fake server, stolen password]
重定向流量不太难
- DNS非常不安全,可以伪造gmail.com的DNS信息,返回给浏览器
- 网络路由器、路由系统、WiFi都不总是安全的
基础证书和CA模式
映射DNS的名称到公钥:用户知道他们想联系的DNS的名称
[Google, CA, gmail.com server, browser, https connection]
一个证书包括:
- DNS名称,比如gmail.com
- 服务器公钥
- CA的ID
- CA秘钥后的签名
浏览器包含CA列表,记录所有可接受的CA的公钥 当浏览器通过https通讯,服务器发送证书,浏览器检查CA签名(用CA列表),然后浏览器要让服务器证明它有私钥
现在中间人攻击更难了,假设用户点击https://gmail.com,攻击者伪装gmail.com,必须要有gmail.com的证书
为什么证书方式还是不完美? 因为如何判断谁拥有DNS的名称不清晰,如果我问CA,“x.com”的证书,CA要怎么判断? 这看起来很难,即使对于大家都知道的名称,比如microsoft.com
更糟的:浏览器的CA列表有超100条
- 这些CA并不都运行良好
- 雇佣的员工并不都可信赖
- 对国家的命令并不都能抵抗
任何CA都可以给任何名称证书, 所以整体的安全取决于最差CA的安全性
结果: 多起“伪造”证书事件,比如gmail.com证书由别人签的 难以预防,难以检测
为什么使用一个在线的DB,其中存放有效证书?
DB服务检测和拒绝伪造的证书,浏览器在使用任何证书前先检查DB
- 如何检测谁拥有这个DNS的名称?如果你不知道,你无法拒绝伪造的证书
- 要允许人们改CA机构、更新证书,或者丢失私钥的情况等,这些情况看起来要第二张证书
- 谁运行它?目前没有全世界都相信的单点验证服务
CT是怎么解决这个问题的额? 它其实是一个审计系统,不直接禁止一切,但域名拥有者规则不能很好定义时,这特性很有用
[gmail.com, CA, CT log server, browser, gmail’s monitor]
基本动作:
- gmail.com想CA申请证书
- CA签发证书给gmail.com
- CA通过CT log服务器注册证书
- log服务器吧证书加进log
- 浏览器连接gmail.com
- gmail.com提供证书给浏览器
- 浏览器请求CT的log服务器,询问证书是否在log中
- 同时
- gmail.com的监视器周期性的拉取全部CT的log
- 扫描所有的证书,找出gmail.com的
- 如果有非自己的其他的证书,则抱怨(complains)
- 因为他们肯定是伪造的
因此:如果浏览器和监视器能看到同样的log,监视器看到伪造的证书可以进行预警, 浏览器要求证书一定在log中,使用log中的证书,浏览器才能感到安全
难的部分:如何确保到家看到同样的log? 当log操作是恶意的时候,和其他恶意的CA密谋
危机:无法检测(即使有恶意的log操作)。 log可以给浏览器伪造的证书,声称在log中, 在浏览器使用后从log删掉,这样监视器不会注意到伪造的证书的(no undetected deletion,无法检测的删除)
危机:无模棱两可(任何人看到相同的内容) log服务器给浏览器伪造的证书,给监视器的是不含伪造证书的log(no undetected equivocation,无法检测的模棱两可)
那么,如果一个CA签发伪造的证书,它必须被加到中心log,这样client才能接受它, 但是它不能被删除,因此域名拥有者最后总能看到它
如何在不信任服务器写log的情况,构建可变/只能添加,而不会分叉的log
第一步:Merkle Tree
[logged certs, tree over them, root]
log服务器维护证书的log, 假设有2次幂的log项(简化) H(a, b)意味着a+b的密码学hash key性质:找不到其他的输入,产生相同的hash
在log项,构建hash的二叉树——Merkle Tree 对每个hash,只有唯一的log序列,如果改变了log。那跟hash也会变 STH(Signed Tree Head)——被log服务器签名的,所以不能否认从根hash发出的证书 只要log服务器展示了STH给我,表明已经承诺了特定的log内容
log服务器如何添加记录到Merkle Tree?
- 假设log上有N项,根hash是H1
- log服务器等待N个新项达到
- 对它们做hash,结果为H2
- 创建新的根H3 = H(H1, H2)
一个log服务器如何证明,证书在给定的STH下
- “包含证明”(proof of inclusion)或者“RecordProof()”或者“Merkle审计证明”(Merkle Audit Proof)
- 因为浏览器不会用不在log中的证书,因此监视器看不到这些证书,无法保障证书不是伪造的
- 证明给定STH,一个证书,log位置,特定的证书一定在那个位置
- 浏览器询问log服务器当前的STH(也有可能拿到假的STH,后续在讨论)
- 考虑log只有两条记录,a和b,STH = H(H(a), H(b))
- 初始化时,浏览器知道STH,而不是a或b
- 浏览器问“a是否在log中?”
- 服务器回复“0”和z=H(b)——这就是证明
- 浏览器检查H(H(a), z) = STH
- 浏览器问“x是否在log中?”——我们知道x不在STH的log下
- log服务器想要说谎,回复yes,想要欺骗浏览器用监视器没看到的伪造证书
- 浏览器知道STH,所以log服务器需要找到一个y,使得H(H(x), H(y)) = STH = H(H(a), H(b)),且x != a
- 但是密码学hash保证这样的性质:无法产生一对M1不等于M2,而H(M1) = H(M2)
- 通过提供更多,你可以拓展为更大的树
- 证明是耗费小的——log(N)次hash对于N个元素的log
- 重要:我们不想让浏览器下载全部的log,因为有百万的证书
要是log服务器给浏览器提供不同的log,且包含伪造的证书,且只发给浏览器这个log的STH,而不发给监视器? 也就是服务器对当前的STH说谎的情况 log服务器可以想浏览器证明伪造证书在log中。 这就是分叉攻击(fork attack)——或者模棱两可(equivocation)
[diagram – linear log, forked]
CT中有可能分叉,但还没完
如何检测分叉/模棱两可(forks/equivocation) 浏览器和监视器要比较STH,保证他们看到相同的log,称为“流言”(gossip)
我们如何判断给定的SYH对没有分叉的可能?如果一个log的版本的比另一个高,他们就不合理
Merkle一致性证明(merkle consistency proof)或TreeProof()
- 给定两个STH:H1、H2,H1下的日志是否是H2下的日志的前缀?
- client请求log服务器去产生这种证明
- 如果证明解决了,log服务器则没有分叉
- 如果没有证明,log服务器可能已经分叉了——展示了不一样的log
- 证明:
- 对每个根hash Hz=H(Hx, Hy)作为树增长,从H1到H2
- 右侧hash——Hy
- client可以计算 H(H(H1,Hy1),Hy2) ……检查是否等于H2
为什么log一致性证明意味着clients看到相同的log? 要是H2是不同log项,且包含H1的派生,也就是log服务器分叉了两个clients 假设H2是H1的下一个更大的2的幂数对数
[draw tree]
clients,知道H1、H2,期待以下的证明:
- 有x使得H2 = H(H1, x)
- 因为log服务器对clients分叉了,则 H2 = H(Hz, y) 且 Hz != H1
- 所以假log服务器要找到x,使得H(H1, x) = H2 = H(Hz, y) where H1 != Hz
- 但是密码学hash保证这不可行:寻找两个产生相同输出的不同输入不切实际
- 所以一致性证明表明H1是H2的前缀,因此log服务器没有对clients分叉
所以,如果浏览器和监视器足够gossiping,要求一致性证明,就能保证他们看到的log是相同的,因此监视器检查的证书和浏览器看到的一样
最后一个证明事项 要是浏览器遇到伪造的证书C1,在log服务器得到有效的证明,但是它实际在分叉的log中以欺骗浏览器
[diagram of fork]
浏览器继续,并使用伪造的C1,但下次浏览器访问log服务器。log服务器有提供了主干和主干的STH 现在但浏览器和监视器标记STH,好像看起来没有发生过什么坏事
浏览器用log一致性证明,防止分叉的切换 浏览器记得(持久化)从log服务器拿到的STH,每次浏览器访问log服务器,得到一个新STH, 浏览器要证明旧的STH是新STH的前缀,因此当log服务器发给浏览器证书,返回的STH也反应了这个证书的信息
[diagram]
所以,如果log服务器对浏览器分叉,它不能切换分叉的,这叫做“分叉一致性”(fork consistency) 只要分叉,就会一直走下去。
所以,下一次浏览器和监视器gossip,就会发现分叉, 所以log服务器就有不分叉的动力
如果发现问题,应该发生什么?
-
log一致性证明失败,也就是遭遇分叉攻击: 这个说明log服务被打扰或管理不当,在调查后,这个log服务器可能会从浏览器提供的列表中删除
- 提供包含证明失败了,即使签了SCT
- 可能表明受到攻击,即向受害浏览器展示了证书,但是它不是监视器从log中看到的
- 可能log服务器处理慢,还没吧证书加进log
- CT log中的伪造证书 比如,证书是欠的mit.edu,但是并不是MIT申请的 需要人去和对应的CA沟通,找出真相 大多是失误,需要撤销证书 如果经常发生或带有明显的恶意,浏览器供应商也许从列表中删除改CA
CT被攻击,会怎样?
- 在浏览器使用证书,监视器检查log的这个档口,还没监视到给定的域名
- 如果有问题,不总能确定会发生什么。
- 谁拥有这个给定的域名?可能伪造的证书是一个事故?
- 当前CT设计/实施中缺少gossip
- 隐私/追踪:浏览器向log服务器请求证明
学到什么?
- key的性质:每方看到同样的log,计算浏览器和域名所有者间有恶意攻击 如果浏览器看到伪造的证书,域名所有者也有一直的性质
- 当预防不了模棱两可的情况,审计是值得思考
- 分叉一致性
- 检测分叉:gossip
下节课将看到更多关于分叉的,关于比特币