Google的证书透明度

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?

  1. 假设log上有N项,根hash是H1
  2. log服务器等待N个新项达到
  3. 对它们做hash,结果为H2
  4. 创建新的根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
    1. 可能表明受到攻击,即向受害浏览器展示了证书,但是它不是监视器从log中看到的
    2. 可能log服务器处理慢,还没吧证书加进log
  • CT log中的伪造证书 比如,证书是欠的mit.edu,但是并不是MIT申请的 需要人去和对应的CA沟通,找出真相 大多是失误,需要撤销证书 如果经常发生或带有明显的恶意,浏览器供应商也许从列表中删除改CA

CT被攻击,会怎样?

  • 在浏览器使用证书,监视器检查log的这个档口,还没监视到给定的域名
  • 如果有问题,不总能确定会发生什么。
    • 谁拥有这个给定的域名?可能伪造的证书是一个事故?
  • 当前CT设计/实施中缺少gossip
  • 隐私/追踪:浏览器向log服务器请求证明

学到什么?

  • key的性质:每方看到同样的log,计算浏览器和域名所有者间有恶意攻击 如果浏览器看到伪造的证书,域名所有者也有一直的性质
  • 当预防不了模棱两可的情况,审计是值得思考
  • 分叉一致性
  • 检测分叉:gossip

下节课将看到更多关于分叉的,关于比特币