译者:飞龙 协议:CC BY-NC-SA 4.0
SSL/TLS 和 HTTPS
**注意:**这些讲座笔记略有修改自 2014 年 6.858 课程网站上发布的笔记。
这节课涉及两个相关主题:
- 如何在比 Kerberos 更大规模上加密保护网络通信?
- 技术:证书
- 如何将网络流量的加密保护整合到 Web 安全模型中?
- HTTPS,安全 cookie 等。
对称与非对称加密
**回顾:**两种加密方案。
-
E
是加密,D
是解密 - 对称密钥加密意味着相同密钥用于加密和解密
-
密文 = E_k(明文)
-
明文 = D_k(密文)
-
- 非对称密钥(公钥)加密:加密和解密密钥不同
-
密文 = E_PK(明文)
-
明文 = D_SK(密文)
-
PK
和SK
分别称为公钥和私钥(秘密密钥)
-
- 公钥加密比对称加密慢几个数量级
- 加密提供数据保密性,但我们通常也希望完整性。
- *消息认证码(MAC)*使用对称密钥可以提供完整性。
- 如果你对更多细节感兴趣,请查看HMAC。
- 可以使用公钥加密进行签名和验证,几乎相反:
- 使用秘密密钥生成签名(计算
D_SK
) - 使用公钥检查签名(计算
E_PK
)
- 使用秘密密钥生成签名(计算
Kerberos
- 中央 KDC 知道所有主体及其密钥。
- 当
A
想要与B
交流时,A
要求 KDC 发放一张票。 - 票据包含一个由 KDC 生成的
A
与B
通话的会话密钥。
为什么 Kerberos 不够?
- 例如,为什么 Web 不基于 Kerberos?
- 可能没有一个单一的 KDC 被信任生成会话密钥。
- 不是每个人都可能在这个单一 KDC 上有帐户。
- 如果用户每次访问网站都联系 KDC,KDC 可能无法扩展。
- 不幸的是,KDC 知道每个用户连接到哪个服务。
- 这些限制在对称加密中很大程度上是不可避免的。
*备选方案:*使用公钥加密
- 假设
A
知道B
的公钥。 - 不想一直使用公钥加密(速度慢)。
- 用于在
A
和B
之间建立安全连接的草案协议:-
A
生成一个随机对称会话密钥S
。 -
A
为PK_B
加密S
,发送给B
。 - 现在我们有
A
和B
之间共享的秘密密钥S
,可以加密和 - 使用对称加密验证消息,类似于 Kerberos。
-
这个草案协议的好处:
-
A
的数据只被B
看到。- 只有
B
(具有SK_B
)才能解密S
。 - 只有
B
才能解密使用S
加密的数据。
- 只有
- 不需要类似 KDC 的中央机构来分发会话密钥。
这个草案有什么问题?
- 对手可以记录并稍后重放
A
的流量;B
不会注意到。- 解决方案:让
B
发送一个随机值(nonce)。 - 将 nonce 合并到最终主密钥
S' = f(S, nonce)
中。 - 通常,
S
被称为预主密钥,S'
被称为主密钥。 - 建立
S'
的过程称为“握手”。
- 解决方案:让
- 对手可以冒充
A
,发送另一个对B
的对称密钥。- 如果
B
在乎A
是谁,有许多可能的解决方案。 - 例如,
B
还选择并使用PK_A
加密的对A
发送对称密钥。 - 然后
A
和B
都使用两个密钥组合的哈希。 - 这大致是 TLS 客户端证书的工作原理。
- 如果
- 对手稍后可以获取
SK_B
,解密对称密钥和所有消息。- 解决方案:使用类似 Diffie-Hellman 的密钥交换协议,
- 提供前向保密,如上次讲座中讨论的。
难题: 如果两台计算机都不知道对方的公钥怎么办?
- 常见方法:使用可信第三方生成证书。
- 证书是元组(名称,公钥),由证书颁发机构签名。
- 含义:证书颁发机构声称名称的公钥是公钥。
-
B
除了发送证书外,还向A
发送一个公钥。 - 如果
A
信任证书颁发机构,继续如上操作。
为什么证书可能比 Kerberos 更好?
- 客户端每次连接到新服务器时无需与 KDC 通信。
- 服务器可以向客户端呈现证书;客户端可以验证签名。
- KDC 不参与生成会话密钥。
- 可以支持没有长期密钥/证书的“匿名”客户端。
保护 Web 浏览器的计划:HTTPS
- 新协议:https 而不是 http(例如,
www.paypal.com/
)。 - 需要保护几样东西:
- (A) 数据在网络上传输。
- (B) 用户浏览器中的代码/数据。
- © 用户看到的 UI。
- (A) 如何确保数据在网络上不被窃听或篡改?
- 使用 TLS(一种使用证书的加密协议)。
- TLS 加密和认证网络流量。
- 协商密码(和其他功能:压缩,扩展)。
- 协商是明文进行的。
- 包括对所有握手消息进行 MAC 认证。
- (B) 如何保护用户浏览器中的数据和代码?
- 目标: 将浏览器安全机制与 TLS 提供的内容连接起来。
- 记住浏览器有两个主要的安全机制:
- 同源策略。
- Cookie 策略(略有不同)。
- 与 HTTPS/TLS 的同源策略。
- TLS 证书名称必须与 URL 中的主机名匹配。
- 在我们的示例中,证书名称必须是 www.paypal.com。
- 也允许一级通配符(*.paypal.com)。
- 浏览器信任多个证书颁发机构。
- 来源(来自同源策略)包括协议。
- http://www.paypal.com/ 与 https://www.paypal.com/ 不同。
- 在这里,我们关心数据的完整性(例如 JavaScript 代码)。
- 结果: 非 HTTPS 页面无法篡改 HTTPS 页面。
- 原因: 非 HTTPS 页面可能已被对手修改。
- 使用 HTTPS/TLS 的 Cookie。
- 服务器证书帮助客户端区分服务器。
- Cookie(用户凭证的常见形式)有一个“安全”标志。
- 安全的 Cookie 只能随 HTTPS 请求发送。
- 非安全的 Cookie 可以随 HTTP 和 HTTPS 请求发送。
- 如果对手篡改 DNS 记录会发生什么?
- 好消息:安全性不依赖于 DNS。
- 我们已经假设对手可以篡改网络数据包。
- 错误的服务器将不知道与证书匹配的正确私钥。
- © 最后,用户可以直接输入凭据。如何确保安全?
- 浏览器中的锁图标告诉用户他们正在与 HTTPS 站点交互。
- 浏览器应该向用户指示站点证书中的名称。
- 用户应验证他们打算提供凭据的站点名称。
这个计划怎么会出错?
- 正如你所料,上述每一步都可能出错。
- 不是详尽的列表,但涉及 ForceHTTPS 想要解决的问题。
1 (A) 密码学
SSL/TLS 的密码部分曾受到一些攻击。
- Rizzo 和 Duong 的攻击可以让对手通过在单个连接上发出许多精心选择的请求来学习一些明文。参考
- 同一人使用压缩进行最近的攻击,在 iSEC 讲座中提到。参考
- 最近,更多的填充预言攻击。参考
- 一些服务器/CA 使用弱加密,例如使用 MD5 的证书。
- 一些客户端选择弱加密(例如,Android 上的 SSL/TLS)。参考
- 但是,密码学很少是系统中最薄弱的部分。
2 (B) 服务器认证
对手可能能够为他人的名字获得证书。
- 以前需要在公司抬头纸上传真请求(但如何检查?)
- 现在通常需要在 root@domain.com 或类似位置接收秘密令牌
- 安全性取决于最不安全证书颁发机构的政策
- 大多数浏览器中有数百个受信任的证书颁发机构
- 2011 年发生了几起 CA 被破坏的事件(gmail、facebook 等的证书)。参考
- 服务器可能被入侵,相应的私钥被盗。
如何处理受损的证书(例如,无效证书或被盗私钥)?
- 证书有到期日期。
- 每次请求都要与 CA 检查证书状态很难扩展。
- 一些 CA 发布的证书吊销列表(CRL),但其中的证书相对较少
- 其中一些(抽查:大多数没有被吊销的证书)。
- 客户端必须定期下载 CRL。
- 如果许多证书被吊销,可能会很慢。
- 如果很少或零个证书被吊销,则不是问题,但并不太有用。
- OCSP:在线证书状态协议。
- 查询证书是否有效。
- 一个问题:OCSP 协议不要求签署“稍后再试”消息。参考
- 用于猜测证书是否正常的各种启发式方法。
- CertPatrol,EFF 的 SSL Observatory 等。
- 不像“证书是否更改那么容易”。网站有时会测试新的 CA。
- 问题:在线吊销检查是软失败。
- 主动网络攻击者可以使检查不可用。
- 浏览器不喜欢在侧通道上阻塞。
- 性能、单点故障、强制门户等问题。[ 参考:https://www.imperialviolet.org/2011/03/18/revocation.html ]
- 实际上,浏览器在重大违规事件后会推送黑名单更新。[ 参考:https://www.imperialviolet.org/2012/02/05/crlsets.html ]
用户忽略证书不匹配错误。
- 尽管证书很容易获得,但许多网站配置错误。
- 有些人不想处理获得证书的(非零)成本。
- 其他人忘记更新它们(证书有到期日期)。
- 最终结果:浏览器允许用户覆盖不匹配的证书。
- 问题在于:人现在成为决定证书是否有效的过程的一部分。
- 开发人员很难确切知道浏览器将接受哪些证书。
- 根据经验,Chrome 显示的约 60% 的绕过按钮被点击通过。(尽管这些数据可能已经过时…)
用户接受无效证书的风险是什么?
- 可能是良性的(过期证书,服务器操作员忘记续订)。
- 可能是中间人攻击,连接到对手的服务器。
- 为什么这是不好的?
- 用户的浏览器将用户的 cookie 发送给对手。
- 用户可能会将敏感数据输入对手的网站。
- 用户可能会认为页面上的数据来自正确的网站。
3 (B) 混合 HTTP 和 HTTPS 内容
- 网页的来源由页面本身的 URL 确定。
- 页面可以有许多嵌入元素:
- Javascript 通过
<SCRIPT>
标签 - CSS 样式表通过
<STYLE>
标签 - Flash 代码通过
<EMBED>
标签 - 图像通过
<IMG>
标签
- Javascript 通过
- 如果对手能够篡改这些元素,可能控制页面。
- 特别是,Javascript 和 Flash 代码可以控制页面。
- CSS:控制较少,但仍然可滥用,尤其是使用复杂的属性选择器。
- 开发人员可能不会包含来自攻击者网站的 Javascript。
- 但是,如果 URL 不是 HTTPS,对手可以篡改 HTTP 响应。
- 另一种方法:明确验证嵌入元素。
- 例如,可以包含正在加载的 Javascript 代码的哈希值。
- 防止对手篡改响应。
- 不需要完整的 HTTPS。
- 可能会在不久的将来在浏览器中部署。参考
4 (B) 保护 cookie
- Web 应用程序开发人员可能会犯错误,忘记了 Secure 标志。
- 用户访问 http://bank.com/ 而不是 https://bank.com/,泄漏 cookie。
- 假设用户只访问 https://bank.com/。
- 为什么这仍然是一个问题?
- 对手可以导致另一个 HTTP 网站重定向到 http://bank.com/。
- 即使用户从未访问任何 HTTP 网站,应用程序代码可能存在错误。
- 一些网站通过 HTTPS 提供登录表单,并通过 HTTP 提供其他内容。
- 在同时使用 HTTP 和 HTTPS 时要小心。
- 例如,Google 的登录服务在请求时创建新的 cookie。
- 登录服务有自己的(安全的)cookie。
- 可以通过加载登录的 HTTPS URL 请求登录到 Google 网站。
- 以前还可以通过不安全的 cookie 登录。
- ForceHTTPS 通过将 HTTP URL 重定向到 HTTPS 来解决问题。参考
- 为什么这仍然是一个问题?
- cookie 完整性问题。
- 在 http://bank.com 上设置的非 Secure cookie 仍然发送到 https://bank.com。
- 无法确定是谁设置了 cookie。
5(C) 用户直接输入凭据
- 钓鱼攻击。
- 用户不检查锁图标。
- 用户不仔细检查域名,不知道要查找什么。
- 例如,拼写错误的域名(paypa1.com),unicode
- Web 开发人员将登录表单放在 HTTP 页面上(目标登录脚本是 HTTPS)。
- 对手可以修改登录表单以指向另一个 URL。
- 登录表单没有受到篡改的保护,用户无法辨别。
ForceHTTPS
ForceHTTPS(本文)如何解决这些问题?
- 服务器可以在用户的浏览器中为自己的主机名设置标志。
- 将 SSL/TLS 证书配置错误变成致命错误。
- 将 HTTP 请求重定向到 HTTPS。
- 禁止非 HTTPS 嵌入( 为它们执行 ForceHTTPS)。
ForceHTTPS 解决了哪些问题?
- 主要是 2、3,某种程度上是 4(见上面的列表)
- 用户接受无效证书。
- 开发人员错误:嵌入不安全的内容。
- 开发人员错误:忘记将 cookie 标记为 Secure。
- 对手通过 HTTP 注入 cookie。
这真的有必要吗?我们只能使用 HTTPS,设置 Secure cookie 等吗?
- 用户仍然可以点击错误,因此对于#2 仍然有帮助。
- 对于#3 来说并不是必要的,假设 Web 开发人员永远不会犯错误。
- 对于#4 仍然有帮助。
- 将 cookie 标记为 Secure 可以确保保密性,但不能保证完整性。
- 主动攻击者可以在 http://bank.com 上提供虚假设置,并设置 cookie。
- 用于 https://bank.com。 (https://bank.com 无法区分)
为什么不为所有人打开 ForceHTTPS?
- HTTPS 站点可能不存在。
- 如果是这样,可能不是同一个站点(https://web.mit.edu 是
- 认证,但 http://web.mit.edu 不是)。
- HTTPS 页面可能期望用户点击通过(自签名证书)。
实施 ForceHTTPS
- ForceHTTPS 位存储在 cookie 中。
- 有趣的问题:
- 状态耗尽(ForceHTTPS cookie 被驱逐)。
- 拒绝服务(强制整个域;通过 JS 强制;通过 HTTP 强制)。
- 为什么 ForceHTTPS 只允许特定主机,而不是整个域?
- 为什么 ForceHTTPS 要求通过标头设置 cookie,而不是通过 JS?
- 为什么 ForceHTTPS 要求通过 HTTPS 设置 cookie,而不是 HTTP?
- 引导(如何获取 ForceHTTPS 位;如何避免隐私泄漏)。
- 可能的解决方案 1:DNSSEC。
- 可能的解决方案 2:在 URL 名称中嵌入 ForceHTTPS 位(如果可能)。
- 如果有一种方法可以从服务器所有者那里获取一些经过身份验证的位(DNSSEC、URL 名称等),我们是否应该直接获取公钥?
- 困难:用户网络不可靠。浏览器不愿意在侧通道请求上阻止握手。
ForceHTTPS 的当前状态
- 一些 ForceHTTPS 的想法已被采纳为标准。
- HTTP Strict-Transport-Security 头部类似于 ForceHTTPS cookie。参考:RFC6797,参考:HTTP Strict Transport Security
- 使用标题而不是魔术 Cookie:
- Strict-Transport-Security:max-age=7884000;includeSubDomains
- 将 HTTP 链接转换为 HTTPS 链接。
- 禁止用户覆盖 SSL/TLS 错误(例如,错误的证书)。
- 可选择应用于所有子域。
- 这有什么用?非安全和伪造的 cookie 可能会泄漏或设置在子域上。
- 可选择为用户提供手动启用的界面。
- 在 Chrome、Firefox 和 Opera 中实施。
- 引导程序在很大程度上尚未解决。
- Chrome 有一个硬编码的预加载列表。
- 使用标题而不是魔术 Cookie:
- IE9,Firefox 23 和 Chrome 现在默认阻止混合脚本。
- 参考:结束混合脚本漏洞,
- 参考:Firefox 中启用混合内容阻止,
- 参考:保护消费者免受恶意混合内容
在这个领域的另一个最近的实验:HTTPS-Everywhere。
- 专注于 ForceHTTPS 的“高级用户”方面。
- 允许用户强制某些域名使用 HTTPS。
- Tor 和 EFF 之间的合作。
- 适用于 Firefox 和 Chrome 的附加组件。
- 附带用于重写流行网站 URL 的规则。
SSL/TLS 中解决问题的其他方法
- 更好的工具/更好的开发人员以避免编程错误。
- 将所有敏感 cookie 标记为 Secure(#4)。
- 避免任何不安全的嵌入(#3)。
- 不幸的是,似乎容易出错。
- 不帮助最终用户(需要开发者参与)。
- EV 证书。
- 尝试解决问题 5:用户不知道在证书中寻找什么。
- 除了 URL,还嵌入公司名称(例如,“PayPal, Inc.”)
- 通常显示为 URL 栏旁边的绿色框。
- 为什么这样更安全?
- 什么情况下实际上会提高安全性?
- 如果用户开始期望 EV 证书,可能间接有助于解决问题 2。
- 黑名单弱加密。
- 浏览器开始拒绝证书上的 MD5 签名(iOS 5,Chrome 18,Firefox 16)
- 以及 Chrome 18、OS X 10.7.4、Windows XP 最近更新后的 RSA 密钥
< 1024
位。 - 甚至被 Chrome 淘汰的 SHA-1。参考:逐步淘汰 SHA1
- OCSP 装订。
- OCSP 响应由 CA 签名。
- 服务器在握手中发送 OCSP 响应,而不是在线查询(#2)。
- 实际上是一个短暂的证书。
- 问题:
- 尚未广泛部署。
- 只能装订一个 OCSP 响应。
- 密钥固定。
- 仅接受由每个站点白名单的 CA 签名的证书。
- 消除对最不安全 CA 的依赖(#2)。
- 目前在 Chrome 中有一个硬编码的站点列表。
- 2011 年 Diginotar 妥协是因为密钥固定。
- 计划添加站点广告固定的机制。
- 参考:IETF 关于 websec 关键固定的草案
- 参考:tack.io
- 与 ForceHTTPS 中的引导困难相同。
其他参考资料
www.imperialviolet.org/2012/07/19/hope9talk.html
RSA 的侧信道攻击
注意: 这些讲义略有修改自 6.858 课程网站 上发布的讲义,时间为 2014 年。
侧信道攻击
- 历史上,担心电磁信号泄露。NSA TEMPEST。
- 广泛地,系统可能需要担心许多意外的方式
- 信息可能会被泄露。
示例设置: 服务器(例如,Apache)有一个 RSA 私钥。
- 服务器使用 RSA 私钥(例如,解密来自客户端的消息)。
- 服务器的计算信息泄露给客户端。
已经研究了许多信息泄漏:
- 解密需要多长时间。
- 解密如何影响共享资源(缓存、TLB、分支预测器)。
- CPU 本身的辐射(射频、音频、功耗等)。
侧信道攻击不一定与加密相关。
- 例如,操作时间与密码中哪个字符不正确有关。
- 或时间与你和某个用户在 Facebook 上有多少共同好友有关。
- 或加载页面在浏览器中需要多长时间(取决于是否被缓存)。
- 或基于点阵打印机的声音恢复打印文本。参考
- 但对密码或密钥的攻击通常是最具破坏性的。
对手可以分析信息泄漏,用它来重建私钥。
- 目前,本文描述的系统上的侧信道攻击是罕见的。
- 例如,Apache web 服务器运行在某个连接到互联网的机器上。
- 通常存在其他一些漏洞,更容易利用。
- 慢慢地成为一个更大的关注点:新的侧信道(虚拟机)、更好的攻击。
- 侧信道攻击更常用于攻击受信任/嵌入式硬件。
- 例如,芯片在智能卡上运行加密操作。
- 通常这些具有较小的攻击面,没有太多其他方式可以进入。
- 如论文所述,一些密码协处理器设计用于避免此类攻击。
“远程时间攻击是实际的” 论文的贡献是什么?参考
- 时间攻击已知已久。
- 本文:可能通过网络攻击标准的 Apache web 服务器。
- 使用了许多关于时间攻击的先前工作的观察/技术。
- 要理解这是如何工作的,首先让我们看一些 RSA 的内部…
RSA:高级计划
- 选择两个随机素数,
p
和q
。- 让
n = p*q
。
- 让
- 今天一个合理的密钥长度,即
|n|
或|d|
,是 2048 位。 - 欧拉函数
phi(n)
:与n
互质的Z_n^*
元素的数量。- 定理 [此处无证明]:
a^(phi(n)) = 1 mod n
,对所有的a
和n
。
- 定理 [此处无证明]:
- 那么,如何加密和解密?
- 选择两个指数
d
和e
,使得m^(e*d) = m (mod n)
,这- 意味着
e*d = 1 mod phi(n)
。
- 意味着
- 加密将是
c = m^e (mod n)
;解密将是m = c^d (mod n)
。
- 选择两个指数
- 如何获得这样的
e
和d
?- 对于
n=pq
,phi(n) = (p-1)(q-1)
。 - 如果我们知道
phi(n)
,很容易计算d=1/e
。扩展欧几里得算法 - 在实践中,选择小的
e
(例如,65537),使加密更快。
- 对于
- 公钥是
(n, e)
。 - 私钥原则上是
(n, d)
。- 注意:
p
和q
必须保密! - 否则,对手可以像我们上面做的那样从
e
计算d
。 - 知道
p
和q
对快速解密也很有帮助。 - 因此,在实践中,私钥也包括
(p, q)
。
- 注意:
RSA 在“安全”使用上有些棘手–如果直接使用 RSA,请小心!
- 密文是可乘的。
-
E(a)*E(b) = a^e * b^e = (ab)^e
。 - 可以让对手操纵加密,生成新的加密。
-
- RSA 是确定性的。
- 加密相同的明文每次都会生成相同的密文。
- 对手可以知道何时重新加密相同的内容。
- 通常通过在加密前对消息进行“填充”来解决。OAEP
- 取明文消息位,加上明文前后的填充位。
- 加密组合位(总位数必须小于
|n|
位)。 - 填充包括随机性,以及固定位模式。
- 有助于检测篡改(例如,密文乘法)。
如何实现 RSA?
- **关键问题:**快速模指数运算。
- 一般来说,是二次复杂度。
- 两个 1024 位数相乘很慢。
- 计算 1024 位数的模很慢(1024 位除法)。
优化 1:赛里斯剩余定理(CRT)。
- 回想一下 CRT 的原理:
- 如果
x==a1 (mod p)
和x==a2 (mod q)
,其中p
和q
是互质的, - 那么就有一个唯一解
x==a (mod pq)
。- 并且,有一种高效的算法来计算
a
。
- 并且,有一种高效的算法来计算
- 如果
- 假设我们想要计算
m = c^d (mod pq)
。 - 可以计算
m1 = c^d (mod p)
,以及m2 = c^d (mod q)
。 - 然后使用 CRT 从
m1
、m2
计算m = c^d (mod n)
;这是唯一且快速的。 - 计算
m1
(或m2
)比直接计算m
快约 4 倍(~二次)。 - 使用 CRT 从
m1
和m2
计算m
的速度与忽略不计。 - 因此,大约加速 2 倍。
优化 2:重复平方和滑动窗口。
- 计算
c^d
的朴素方法:将c
乘以自身,d
次。 - 更好的方法,称为重复平方:
-
c^(2x) = (c^x)²
-
c^(2x 1) = (c^x)² * c
- 要计算
c^d
,首先计算c^(floor(d/2))
,然后使用上述方法计算c^d
。 - 递归应用,直到计算到
c⁰ = 1
。 - 平方次数:
|d|
(表示d
所需的位数)。 - 乘法次数:
d
中的 1 位数。
-
- 更好的方法(有时),称为滑动窗口:
-
c^(2x) = (c^x)²
-
c^(32x 1) = (c^x)³² * c
-
c^(32x 3) = (c^x)³² * c³
- …
-
c^(32x z) = (c^x)³² * c^z
,通常情况下(其中z<=31
)。 - 可以预先计算所有必要的
c^z
幂的表,存储在内存中。 - 选择 2 的幂常数(例如,32)取决于使用情况。
- 成本:额外内存,额外时间来预先计算幂。
- 注意:仅预先计算
c
的奇数次幂(对于偶数使用第一条规则)。 - OpenSSL 使用 32(具有 16 个预先计算的条目的表)。
-
优化 3:蒙哥马利表示。
- 每次(平方或乘法后)都进行
mod p
减少是昂贵的。- 典型实现:进行长除法,找到余数。
- 难以避免减少:否则,值会呈指数增长。
- 理念(由彼得·蒙哥马利提出):在另一种表示中进行计算。
- 将基数(例如
c
)提前转换为不同的表示。 - 在这种表示中执行模运算(会更便宜)。
- 完成后将数字移回原始表示。
- 理想情况下,减少的节省应超过移位的成本。
- 将基数(例如
- 蒙哥马利表示:将所有内容乘以某个因子 R。
-
a mod q <-> aR mod q
-
b mod q <-> bR mod q
-
c = a*b mod q <-> cR mod q = (aR * bR)/R mod q
- 每个在蒙哥马利空间中的乘法(或平方)需要除以
R
。
-
- 蒙哥马利表示中模乘法为何更便宜?
- 选择
R
使得除以R
更容易:R = 2^|q|
(1024 位密钥为2⁵¹²
)。 - 因为我们除以
R
,通常不需要进行mod q
。-
|aR| = |q|
-
|bR| = |q|
-
|aR * bR| = 2|q|
-
|aR * bR / R| = |q|
-
- 如何便宜地除以
R
?- 仅当低位为零时才有效。
- 观察: 因为我们关心值
mod q
,所以q
的倍数并不重要。 - 技巧: 向被除以
R
的数字添加q
的倍数,使低位为 0。- 例如,假设
R=2⁴ (10000)
,q=7 (111)
,将x=26 (11010)
除以 R。 -
x 2q = (二进制) * 101000
-
x 2q 8q = (二进制) 1100000
- 现在,可以轻松地除以
R
:结果是二进制 110(或 6)。 - 通常,总是可能的:
-
q
的最低位为 1(q
是质数),因此可以"击倒"任何位。 - 要"击倒"比特
k
,添加2^k * q
- 要击倒低位
l
,添加q*(l*(-q^-1) mod R)
- 然后,除以
R
意味着简单地丢弃低零位。
- 例如,假设
- 选择
- 一个仍未解决的问题: 结果将会
< R
,但可能会> q
。- 如果结果恰好大于
q
,需要减去q
。 - 这被称为"额外减少"。
- 计算
x^d mod q
时,Pr[额外减少] = (x mod q) / 2R
。- 这里,假设
x
已经处于蒙哥马利形式。 - 直觉: 随着我们乘以更大的数字,将更频繁地溢出。
- 这里,假设
- 如果结果恰好大于
优化 4:高效乘法。
- 如何将 512 位数字相乘?
- 表示:将其分解为 32 位值(或任何硬件支持的值)。
- Naive 方法:逐对乘以所有 32 位组件。
- 就像你在纸上逐位相乘数字一样。
- 如果两个数字分别具有
n
和m
个组件,则需要O(nm)
时间。 - 如果两个数字接近,则为
O(n²)
。
- 卡拉兹巴乘法: 假设两个数字具有相同数量的组件。
-
O(n^log_3(2)) = O(n¹.585)
时间。 - 将两个数字(
x
和y
)分成两个组件(x1
,x0
和y1
,y0
)。-
x = x1 * B x0
-
y = y1 * B y0
- 例如,将 64 位数字分成 32 位组件时,
B=2³²
。
-
- Naive:
x*y = x1y1 * B² x0y1 * B x1y0 * B x0y0
- 四次乘法:
O(n²)
- 四次乘法:
- 更快:
x*y = x1y1 * (B² B) - (x1-x0)(y1-y0) * B x0y0 * (B 1)
- …
= x1y1 * B² ( -(x1-x0)(y1-y0) x1y1 x0y0 ) * B x0y0
- 只需三次乘法,以及几次加法。
- …
- 递归应用此算法以继续分割为更多的一半。
- 有时被称为 “递归乘法”。
- 有意义地更快(没有隐藏的大常数)
- 对于 1024 位密钥,“
n
” 这里是 16 (512/32)。 -
n² = 256
-
n¹.585 = 81
- 对于 1024 位密钥,“
-
- 乘法算法需要决定何时使用 Karatsuba 而不是 Naive。
- 两种情况很重要:两个大数 和 一个大数 一个小数。
- OpenSSL:如果组件数量相等,则使用 Karatsuba,否则使用 Naive。
- 在一些中间情况下,Karatsuba 也可能胜出,但 OpenSSL 忽略了它,
- 根据这篇论文。
SSL 如何使用 RSA?
- 服务器的 SSL 证书包含公钥。
- 服务器必须使用私钥来证明其身份。
- 客户端使用服务器的公钥加密后向服务器发送随机位。
- 服务器解密客户端的消息,使用这些位生成会话密钥。
- 实际上,服务器还验证消息填充。
- 然而,仍然可以测量直到服务器以某种方式响应的时间。
服务器上 解密流水线 的图示:
代码语言:javascript复制 * CRT * To Montgomery * Modular exp
--> * c_0 = c mod q --> * c'_0 = c_0*R mod q --> * m'_0 = (c'_0)^d mod q
/
/ * Use sliding window for bits
/ * of the exponent d
c * Karatsuba if c'_0 and q have
* same number of 32-bit parts
* Extra reductions proportional
* to ((c'_0)^z mod q) / 2R;
--> ... * z comes from sliding window
- 然后,计算
m_0 = m'_0/R mod q
。 - 然后,使用 CRT 结合
m_0
和m_1
得到m
。 - 然后验证
m
中的填充。 - 最后,以某种方式使用有效载荷(SSL 等)。
为 Brumley 论文中描述的攻击设置
- 受害者 Apache HTTPS 网络服务器使用 OpenSSL,在内存中有私钥。
- 连接到斯坦福校园网络。
- 对手控制校园网络上的某些客户端机器。
- 对手向服务器发送特制的消息中的密文。
- 服务器解密密文,找到垃圾填充,返回错误。
- 客户端测量响应时间以获取错误消息。
- 利用响应时间猜测
q
的位。
- 总体响应时间大约为 5 毫秒。
- 请求之间的时间差大约为 10 微秒。
- 什么导致时间变化?
- Karatsuba 与 Naive
- 额外的减少
- 一旦猜测足够多的
q
位,就可以因式分解n=p*q
,从e
计算d
。 - 大约 1M 次查询似乎足以获取 1024 位密钥的 512 位
p
和q
。- 只需猜测
p
和q
的前 256 位,然后使用另一种算法。
- 只需猜测
Brumley 论文中的攻击
- 查看 远程定时攻击是可行的 论文,详细内容请参考末尾的 参考文献 部分。
- 让
q = q_0 q_1 .. q_N
,其中N = |q|
(比如,对于 1024 位密钥,假设为 512 位)。 - 假设我们知道
q
的高阶位j
个数字(从q_0
到q_j
)。 - 构造两个近似值的
q
,猜测q_{j 1}
是 0 或 1:-
g = q_0 q_1 .. q_j 0 0 0 .. 0
-
g_hi = q_0 q_1 .. q_j 1 0 0 .. 0
-
- 让服务器执行模幂运算 (
g^d
) 来猜测。- 我们知道
g
必然小于q
。 - 如果
g
和g_hi
都小于q
,花费的时间不应该有太大变化。 - 如果
g_hi
大于q
,花费的时间可能会明显变化。-
g_hi mod q
很小。 - 较少时间:Montgomery 中减少额外的减少。
- 更多时间:从卡拉茨巴切换到普通乘法。
-
- 知道所花费的时间可以告诉我们 0 还是 1 是正确的猜测。
- 我们知道
- 如何让服务器对我们的猜测执行模指数运算?
- 将我们的猜测发送给服务器,就好像它是随机性的加密。
- 一个问题:服务器将把我们的消息转换为蒙哥马利形式。
- 由于蒙哥马利的
R
是已知的,将(g/R mod n
)作为消息发送给服务器。
- 如何确定时间差应该是正数还是负数?
- 论文似乎暗示这并不重要:只需寻找大的差异。
- 图 3a 显示了每个比特猜测的测量时间差异。
- 卡拉茨巴与普通乘法发生在 32 位边界处。
- 前 32 位:额外的约简占主导地位。
- 接下来的位:卡拉茨巴与普通乘法的支配。
- 在某个时刻,额外的约简再次占主导地位。
- 如果两种效应的时间差抵消会发生什么?
- 图 3,关键 3。
- 更大的邻域会稍微改变平衡,揭示非零间隙。
- 论文如何获得准确的测量结果?
- 客户机使用处理器的时间戳计数器(在 x86 上为
rdtsc
)。 - 进行多次测量,取中位数值。
- 不清楚为什么要中位数;最小值似乎才是真正的计算时间。
- 一个问题:由于滑动窗口,对
g
的乘法相对较少。 - 解决方案:通过获取与
g
接近的值进行更多的乘法运算(对g_hi
同样适用)。 - 具体来说,探测
g
的“邻域”(g, g 1, .., g 400
)。
- 客户机使用处理器的时间戳计数器(在 x86 上为
- 为什么要探测
g
的 400 个值的邻域,而不是测量g
400 次?- 考虑我们试图处理的噪音类型。
- (1) 与计算无关的噪音(例如中断,网络延迟)。
- 当我们多次测量相同的事物时,这种情况可能会消失。
- 参见论文中的图 2a。
- (2) 与计算相关的“噪音”。
- 例如,通过滑动窗口将
g³
和g_hi³
相乘需要不同的时间。 - 重复的测量将返回相同的数值。
- 不会帮助确定是通过
g
还是g_hi
进行更多的约简。 - 参见论文中的图 2b。
- 例如,通过滑动窗口将
- 邻域值平均出第二种噪音。
- 由于邻域值相邻,仍具有大致相同数量的约简。
如何避免这些攻击?
- 解密时间的定时攻击:RSA 盲化。
- 选择随机的
r
。 - 将密文乘以
r^e mod n
:c' = c*r^e mod n
。 - 由于 RSA 的乘法性质,
c'
是m*r
的加密。 - 解密密文
c'
以获取消息m'
。 - 将明文除以
r
:m = m'/r
。 - 根据布鲁姆利的论文,OpenSSL 的 CPU 开销约为 10%。
- 选择随机的
- 使所有代码路径在执行时间方面可预测。
- 困难,编译器将努力消除不必要的操作。
- 阻止了高效的特殊情况算法。
- 难以预测执行时间:指令不是固定时间的。
- 我们能否剥夺对精确时钟的访问?
- 对于我们控制的机器上的单线程攻击者是可以的。
- 可以向合法计算添加噪音,但攻击者可能会进行平均。
- 可以对合法计算进行量化,但会有一定的性能成本。
- 但通过"睡眠"量化,吞吐量仍然可能泄漏信息。
我们应该对这些攻击感到多么担忧?
- 开发利用程序相对棘手(但这是一个一次性问题)。
- 可能会注意到服务器上的攻击(许多连接请求)。
- 尽管在繁忙的 Web 服务器集群上可能不那么容易?
- 对手必须在网络方面靠近。
- 对于对手来说并不是一个大问题。
- 可以对更多查询进行平均,共同定位附近(Amazon EC2),
- 在附近的机器人或浏览器上运行等。
- 对手可能需要知道 OpenSSL 的版本、优化标志等。
- 依赖这样的防御措施是个好主意吗?
- 这会带来多大的障碍?
- 如果对手发动攻击,后果相当严重(密钥泄露)。
其他类型的时序攻击
- 用于猜测密码的页面错误时序 [Tenex 系统]
- 假设内核提供了一个系统调用来检查用户的密码。
- 逐字节检查密码,当发现不匹配时返回错误。
- 对手对齐密码,使第一个字节位于页面末尾,
- 密码的其余部分在下一页。
- 以某种方式安排第二页被交换到磁盘。
- 或者完全取消映射下一页(使用等效的
mmap
)。
- 或者完全取消映射下一页(使用等效的
- 测量猜测密码时返回错误所需的时间。
- 如果花费了很长时间,内核必须从磁盘中读取第二页。
- 或者,如果取消映射,如果崩溃,那么内核会尝试读取第二页。
- 意味着第一个字符是正确的!
- 如果花费了很长时间,内核必须从磁盘中读取第二页。
- 可以在
256*N
次尝试中猜出一个N
字符的密码,而不是256^N
次。
- 假设内核提供了一个系统调用来检查用户的密码。
- 缓存分析攻击: 处理器的缓存由所有进程共享。
- 例如:访问滑动窗口的一个倍数会将其带入缓存。
- 在缓存中必然会驱逐其他内容。
- 恶意进程可能会用大数组填充缓存,观察被驱逐的内容。
- 根据被驱逐的偏移量猜测指数(
d
)的部分。
- 缓存攻击在"移动代码"中可能会有问题。
- 在您的桌面或手机上运行的 NaCl 模块、Javascript、Flash 等。
- 网络流量时序/分析攻击。
- 即使数据被加密,其密文大小仍然与明文大小相近。
- 最近的论文表明可以通过大小、时序推断出许多关于 SSL/VPN 流量的信息。
- 例如,Fidelity 允许客户通过 SSL 网站管理股票。
- 网站为每支股票显示某种饼图图像。
- 用户的浏览器请求所有用户的股票图像。
- 对手可以枚举所有股票饼图图像,知道大小。
- 可以根据数据传输的大小推断用户拥有的股票。
- 类似于本学期早些时候客座讲座中提到的 CRIME 攻击。
参考资料
- 远程时序攻击是实际的
- 为了好玩和利润而缺失缓存
- AES 的高效缓存攻击及对策
- 离开我的笔记本电脑:针对个人电脑的物理侧信道密钥提取攻击
- 跨虚拟机侧信道及其用于提取私钥
- Ed25519:高速高安全性签名
用户认证
注意: 这些讲座笔记略有修改,来自 2014 年 6.858 课程网站上发布的内容。
核心挑战: 人类用户如何向程序证明其身份?
- 是否有任何完全主导密码的解决方案?
- 乍一看,密码似乎很糟糕。
- 低熵
-->
容易让攻击者猜到它们。 - 用于密码的备用安全问题也具有低熵。
- 用户经常为多个站点使用相同的密码。
- 低熵
- 正如今天课堂上的论文所述,“密码继续在所有其他终端用户认证方法上占主导地位,这对安全研究人员来说是一个重大尴尬。”
- 但是…是否实际上有一种认证方案完全主导密码?
- 今天讲座的计划:
- 查看当前密码方案的工作原理。
- 讨论认证方案的理想属性。
- 查看其他认证方案与密码的比较。
密码
密码是用户和服务器之间共享的秘密。
- 天真的实现: 服务器有一个将用户名映射到明文密码的表。
- 问题: 如果攻击者入侵服务器,可以恢复所有用户/密码对。
- 改进方案: 服务器存储此表:
user_name --> hash(user_password)
- 用户客户端向服务器提供明文密码,服务器对明文进行哈希并进行表查找。
- 优势: 哈希函数难以反转,因此攻击者难以执行暴力攻击。然而…
- 问题: 攻击者不必对所有可能的密码启动低效的暴力搜索 – 实际用作密码的字符串集相当小!
- 偏斜分布:前
5000
个密码值覆盖20%
的用户。 - 雅虎密码研究:经验法则密码包含
10-20 bits
的熵。 - 哈希函数优化性能;这有助于攻击者!
- 例子: 一台笔记本电脑可以以每秒约
2M SHA1 ops/sec
的速度计算 SHA1。即使密码具有20 bits
的熵,也可以每秒破解一个帐户。
- 例子: 一台笔记本电脑可以以每秒约
- 偏斜分布:前
- 服务器可以使用计算成本昂贵的密钥派生函数(例如,PBKDF2 或 BCrypt)。
- 这些函数具有可调整的成本,因此它们可以任意缓慢。
- 例如:可以使哈希成本为 1 秒 – 比 SHA1 慢
O(1M)
倍。 - 内部通常使用慢哈希进行重复哈希。
- 问题: 对手可以构建"彩虹表"。
- 密码到哈希映射表。
- 计算成本高昂,但允许攻击者之后有效地反转哈希。
- 为了最大化成本/效益权衡,攻击者只需为常见密码字典构建一个彩虹表。
- 大致:1 秒昂贵的哈希
|-> 1M 秒 = 10 天
来哈希常见密码。之后,可以非常快速地破解任何密码数据库中的常见密码。
- 更好的解决方案: 服务器可以使用密码盐。
- 在密码哈希中输入一些额外的随机性:H(salt, pw)。
- 盐值从哪里来?它以明文形式存储在服务器上。
- Q: 如果对手也能破解盐,为什么这样做更好?
- A: 攻击者无法使用单个彩虹表来检查哈希匹配 – 相同密码使用不同盐将具有不同的哈希值!
- 最佳实践:
- 选择一个长的随机盐。
- 每次用户更改密码时选择一个新的盐。
客户端应该如何将密码传输到服务器?
- 不好的主意: 明文发送密码。
- 稍微好一点: 通过加密连接发送密码。
- 缺点: 连接可能被假冒服务器的攻击者拦截(加密并不一定意味着服务器已经向客户端进行了身份验证!)。中间人攻击者然后可以使用窃取的密码冒充用户。
- Q: 如果客户端发送密码的哈希而不是原始密码呢?
- A: 并不会为我们提供额外的权力,因为哈希仍然可以被攻击者重放。
- 故事寓意: 加密和哈希并不会自动增加安全性 – 你需要考虑你想要实现的安全性质,并具体的加密和哈希可以实现这些目标的方式。
- 缺点: 连接可能被假冒服务器的攻击者拦截(加密并不一定意味着服务器已经向客户端进行了身份验证!)。中间人攻击者然后可以使用窃取的密码冒充用户。
- 更好的主意: 挑战/响应协议。
例子:
代码语言:javascript复制 Client Server
Hi, I'm Alice.
---------------->
Challenge C
<----------------
H(C || password)
----------------->
- Server checks whether the
response is H(C || password).
- 忽略中间人(MITM)攻击,服务器现在确信用户是 Alice。
- 如果服务器是攻击者并且之前不知道密码,那么攻击者仍然不知道密码。
- Q: 我们如何防止服务器基于
H()
值进行暴力猜测密码? - A1: 昂贵的哈希 盐。
- A2: 允许客户端也选择一些随机性:防范彩虹表。
- Q: 我们如何防止服务器基于
- 为了避免在服务器上存储真实密码,使用类似SRP的协议。
- 高级思想: 给定安全参数
g
,客户端计算v = g^(hash(salt, password))
并将v
和salt
发送到服务器。客户端和服务器可以利用对g
和v
的共享知识建立临时密钥(该协议利用了攻击者难以执行模N
下的离散对数的事实;RSA 也利用了这一观察结果)。 - 实施挑战/响应通常意味着改变客户端和服务器。
为了防止暴力破解攻击,我们可以实施反锤击防御。
- 例子: 限制密码猜测次数;在太多错误猜测后实施超时期。
- 限制猜测速率非常重要,因为密码的熵很低!
- 许多网站对密码施加要求(例如长度,使用标点等特殊字符)。
- 实际上,重要的是熵!格式要求很少转化为更高的熵。
- 一个称职的字典攻击者可以模拟密码约束并生成彩虹表;即使有约束,人们仍会选择符合先验字符分布的密码。
- Telepathwords:
telepathwords.research.microsoft.com/
- 当您输入潜在的密码字母时,尝试使用启发式猜测下一个字母!
- 常见密码(例如,通过密码数据库泄漏)
- 来自网站的流行短语
- 用户在选择字符时常见的偏见(例如,使用相邻键来输入相邻的密码字符)
- 当您输入潜在的密码字母时,尝试使用启发式猜测下一个字母!
- Kerberos v4 和 v5 在没有预身份验证的情况下容易受到离线猜测的影响:
www.gnu.org/software/shishi/wu99realworld.pdf
- 任何人都可以向 KDC 请求使用用户密码加密的票证,即 KDC 不会验证请求(尽管响应将使用
K_c
加密)。 - 攻击者可以尝试暴力破解猜测用户的密码–这很容易并行化。由于票据授予票据具有已知格式,攻击者可以确定解密何时成功。
- 在 Kerberos v5 中,票证请求者必须在请求中包含
{ timestamp }_{K_c}
,以证明对K_c
的了解。
- 任何人都可以向 KDC 请求使用用户密码加密的票证,即 KDC 不会验证请求(尽管响应将使用
密码恢复非常重要,但经常被忽视。
- 人们经常关注密码的熵,但如果恢复问题可以用来重置密码,密码认证方案的强度为
min(password_entropy, recovery_question_entropy)
。 - 恢复问题通常很容易被猜到。在一个著名的例子中,有人通过猜测萨拉·佩林的安全问题的答案获得了对她的雅虎地址的访问权限。
- 固有低熵(“你最喜欢的颜色是什么?” “你最好朋友的名字是什么?”)
- 通过社交媒体资料泄露的答案(“你最喜欢的电影是什么?”)
- 自动生成的问题通常很容易回答(“5 5 等于多少?”)
取代密码的追求
在今天的阅读中,作者提出了一堆可以用来评估认证方案的因素(目标是确定密码是否像它们看起来那样糟糕)。作者考虑了三个高级指标:可用性、部署性和安全性。
- **可用性:**用户与认证方案交互的难易程度如何?
- 易学性:
- “不了解方案的用户可以轻松地弄清楚并学会它。”
- 这是密码方案如此受欢迎的一个关键原因!
- 不经常出现的错误:
- “用户必须执行的登录任务通常在由合法和诚实的用户执行时成功。”
- 这是用户选择易于猜测密码的重要原因。
- 用户可扩展性:
- “使用方案登录数百个帐户不会增加用户的负担。”
- …解释了为什么人们经常重复使用密码或为基本密码创建一个简单的每个站点唯一化方案。
- 轻松从认证令牌丢失中恢复:
- 密码的优势在于它们易于重置。
- 无需携带
- 密码的另一个优势。
- 易学性:
- 可部署性: 将身份验证方法整合到实际系统中有多容易?
- 与服务器兼容:
- “在验证者端,该方案与基于文本的密码兼容。提供者不必更改其现有的身份验证设置以支持该方案。”
- 与浏览器兼容:
- “用户不必更改他们的客户端以支持该方案。如果方案要求安装插件或任何需要管理员权限的软件,则无法提供这种好处。”
- 易访问:
- “能够使用密码的用户不会因残疾或其他身体(非认知)状况而无法使用该方案。”
- 可部署性非常困难:很难让用户或服务器大规模更新!
- 密码在这一类别中表现良好,默认情况下,因为作者将“可部署性”定义为系统与当前密码基础设施整合程度。然而,密码在下一个类别中表现不佳……
- 与服务器兼容:
- 安全性: 身份验证方案可以防范哪些攻击?
- 对物理观察具有弹性:
- “在观察用户进行一次或多次身份验证后,攻击者无法冒充用户。如果方案只能通过重复观察 10-20 次以上才能被破解,我们授予准弹性对物理观察的方案。攻击包括肩窥、拍摄键盘、录制按键声音或热成像键盘。”
- 密码未通过此测试,例如,可以通过拍摄键盘或录制按键声音来捕获密码。
- 对有针对性的冒充具有弹性:
- “通过利用个人细节(出生日期、亲属姓名等)的知识,熟人(或熟练的调查员)无法冒充特定用户。个人知识问题是在这一点上失败的典型方案。”
- 作者表示密码是“准抗性”的,因为他们找不到任何研究表明您的朋友或熟人可以轻松猜出您的密码。
- 对受限制的猜测具有弹性:
- “一个攻击者的猜测速率受到验证者的限制,不能成功猜测出大部分用户的秘密……缺乏这种好处意味着惩罚那些经常让用户选择的秘密从一个小而众所周知的子集中选择的方案。”
- 密码失败是因为熵值低 分布倾斜。
- 对不受限制的猜测具有弹性:
- “只受可用计算资源限制的猜测速率的攻击者无法成功猜测出大部分用户的秘密。例如,如果一个能够尝试每个账户最多 2⁴⁰ 甚至 2⁶⁴ 次猜测的攻击者仍然只能达到不到 1%的账户,我们可能会授予这一好处。缺乏这一好处旨在惩罚那些凭证空间不足以抵御来自一个小而众所周知的子集的暴力搜索的方案。”
- 密码失败是因为它们具有低熵和偏斜分布。
- 对内部观察具有弹性:
- “攻击者无法通过拦截用户设备内的用户输入(例如,通过键盘记录恶意软件)或窃听证明者和验证者之间的明文通信来冒充用户(我们假设攻击者也可以击败 TLS,也许通过 CA)。这惩罚了那些不具备重放抵抗性的方案,无论是因为它们发送静态响应还是因为它们的动态响应对策可以通过少数观察被破解。这一好处假定通用设备(如软件可更新的个人计算机和手机)可能包含恶意软件,但专门用于该方案的硬件设备可以做到无恶意软件。”
- 密码失败是因为它们是静态令牌:一旦你有了一个,你可以使用它直到它过期或被撤销。
- 对网络钓鱼具有弹性:
- “模拟有效验证器的攻击者(包括通过 DNS 操纵)无法收集以后可以用来冒充用户向实际验证器进行身份验证的凭据。这惩罚了允许网络钓鱼者让受害者在类似网站上进行身份验证,然后将收集的凭据用于真正网站的方案。”
- 密码失败:网络钓鱼攻击非常普遍!
- 无信任第三方:
- “该方案不依赖于一个可信任的第三方(除了证明者和验证者),后者在遭受攻击或变得不可信任时,可能会危及证明者的安全或隐私。”
- 这一属性提出了一个重要观点:如果我们可以信任一个方当来存储密码、运行密码服务器等,许多身份验证问题将变得更容易。然而,单点故障是不好的,因为攻击者可以将所有精力集中在那一点上!
- 对其他验证者泄露具有弹性:
- “验证者可能泄露的任何信息都不能帮助攻击者冒充用户向另一个验证者进行身份验证。这惩罚了那些在一个提供者内部欺诈或对一个后端的成功攻击危及用户在其他网站账户的方案。”
- 这一属性与无信任第三方有关。为了避免中心化故障点,我们希望引入一些分布式身份验证的概念:然而,这是否意味着系统的强度仅取决于其最薄弱的环节?
- 回想一下 HTTPS,以及一个糟糕的证书颁发机构如何说服浏览器接受任意站点的伪证书。安全性取决于最不安全的 CA 的强度!
- 作者表示,密码失败是因为人们经常在不同网站上重复使用密码。
- 这一属性与无信任第三方有关。为了避免中心化故障点,我们希望引入一些分布式身份验证的概念:然而,这是否意味着系统的强度仅取决于其最薄弱的环节?
- “验证者可能泄露的任何信息都不能帮助攻击者冒充用户向另一个验证者进行身份验证。这惩罚了那些在一个提供者内部欺诈或对一个后端的成功攻击危及用户在其他网站账户的方案。”
- 对物理观察具有弹性:
生物特征识别
生物特征识别: 利用个人外貌或行为的独特方面。
- 密钥空间有多大?
- 指纹: ~13.3 位。
- 虹膜扫描: ~19.9 位。
- 语音识别: ~11.7 位。
- 因此,熵的位数大致与密码相同。
生物特征识别与密码
代码语言:javascript复制 Usability metric Passwords Biometrics
--- --- ---
Easy-to-learn: Yes Yes
Infrequent errors: Quasi-yes No
Scalable for users: No Yes
Easy recovery: Yes No
Nothing to carry: Yes Yes
Usability score: 3.5 vs 3
Deployability metric Passwords Biometrics
--- --- ---
Server-compatible: Yes No
Browser-compatible: Yes No
Accessible: Yes Quasi-yes (entering biometrics is error-prone)
Deployability score: 3 vs 0.5
Security metric Passwords Biometrics
--- --- ---
Res-to-Phys-Obs: No Yes
Res-to-Trgtd-Imp: Quasi-yes No (e.g., replaying voice recording, lifting fingerprints from surfaces)
Res-to-Thrtld-Guess: No Yes
Res-to-UnThrtld-Guess: No No (key space isn't much bigger than that of passwords)
Res-to-Internal-Obv: No No (captured biometric data can be replayed)
Res-to-Phishing: No No
No-trusted-3rd-Party: Yes Yes
Res-Other-Ver-Leaks: No No (same biometrics are used by all verifiers)
Security score: 1.5 vs 3
因此,最终得分是 8 对 6.5。当然,每个类别可以分配非单位权重,但关键是生物特征识别并不明显比密码“更好”!
有些目标似乎很难同时实现。
代码语言:javascript复制 Memorywise-Effortless Nothing-to-Carry.
Memorywise-Effortless Resilient-to-Theft.
// Either the user remembers something, or
// it can be stolen (except for biometrics).
Server-Compatible Resilient-to-Internal-Observation.
Server-Compatible Resilient-to-Leaks-from-Other-Verifiers.
// Server compatible means sending a password.
// Passwords can be stolen on user machine,
// replayed by one server to another.
多因素认证(MFA):深度防御
- 需要用户使用两种或更多身份验证机制进行身份验证。
- 机制应涉及不同的模态!
- 您所知道的东西(例如,密码)
- 您拥有的东西(例如,手机,硬件令牌)
- 您是什么(例如,生物特征)
- 思路是攻击者必须窃取/破坏多个身份验证机制才能冒充用户(例如,攻击者可能猜测密码,但无法访问用户的手机)。
- 例如:谷歌的双因素认证需要密码加上一个可以通过短信接收授权码的手机。
- 例如:AWS 的双因素认证需要密码和一个“MFA 设备”(运行身份验证应用程序的智能手机,或专用安全令牌或安全卡)。Amazon MFA
- 多因素认证是个好主意,但实证研究表明,如果用户除了密码外还提供第二个身份验证因素,用户会选择更弱的密码!
家庭作业问题
家庭作业问题的潜在答案是什么?哪些因素很重要?
- 登录公共 Athena 机器?
- 对内部观察具有弹性:在机器上轻松安装恶意软件。
- 对物理观察具有弹性? MIT ID 可能是一个值得利用的好东西(将其用作智能卡)。
- 生物特征识别?不受信任的终端,可能不是一个很好的计划。
- 从网吧访问 Facebook?
- 在这里不是一个好主意使用密码管理器。
- 数据的敏感程度有多高?
- 可能被用于认证到其他网站!(要么是“使用 Facebook 登录”,要么是通过回答个人安全问题来重置密码。)
- 从 ATM 取款?
- 安全性非常重要。
- 对物理观察具有弹性。
- 对盗窃具有弹性。
- 可能是可信的终端:生物特征识别可能值得考虑。(然而,在实践中,银行可能不想信任终端。)
- 您可能还关心对个别交易进行身份验证!
- 防止对手使用被盗的凭证进行不同的、由攻击者选择的操作。
- 例如:也许用户只需使用密码就能查看余额,但如果她想要取款,她就需要使用手机进行双因素认证。
- 安全性非常重要。
结论
论文结论:没有一个认证方案明显优于密码!例如,根据作者的说法,CAP 读卡器在安全性方面得分完美!
- CAP 读卡器是由万事达卡设计用来保护在线银行交易。
- 用法:
- 将您的信用卡插入看起来像手持计算器的 CAP 读卡器中。
- 输入 PIN 码(绕过键盘记录器!)。
- 读卡器与卡片的嵌入式处理器通信,输出一个 8 位数码,用户将其提供给网站。
分析:
代码语言:javascript复制 CAP reader
Easy-to-learn: Yes
Infrequent errors: Quasi-yes
Scalable for users: No (users require card PIN per verifier)
Easy recovery: No
Nothing to carry: No
Score: 1.5
CAP reader
Server-compatible: No
Browser-compatible: Yes
Accessible: No (blind people can't read 8-digit code)
Score: 1
CAP reader
Res-to-Phys-Obs: Yes
Res-to-Trgtd-Imp: Yes __ One-time codes!
Res-to-Thrtld-Guess: Yes /
Res-to-UnThrtld-Guess: Yes/
Res-to-Internal-Obv: Yes Dedicated device
Res-to-Phishing: Yes One-time codes
No-trusted-3rd-Party: Yes Each site is its own verifier
Res-Other-Ver-Leaks: Yes One-time codes
Score: 8
- 因此,
密码=8
,CAP 读卡器=10.5
。然而,CAP 读卡器没有占领世界的原因(请参阅低可用性和可部署性得分)。 - 在实践中,可部署性和可用性通常比安全性更重要。
- 迁移成本(编码 调试工作,用户培训)让开发人员感到紧张!
- 方案越不可用,用户就越会抱怨(并尝试选择更容易受攻击者攻击的认证令牌)。
- 一些情况可能会给不同的评估指标分配不同的权重。
- 例子:在军事基地上,基于硬件的令牌的安全性优势可能超过可用性和可部署性的问题。
私密浏览模式
注意: 这些讲座笔记是从 2014 年 6.858 课程网站上发布的笔记稍作修改而来。
私密浏览:目标、定义、威胁模型
隐私的目标是什么?
- 模糊的理想:(某个)用户的活动与许多其他用户的活动不可区分。
- 今天我们将讨论网络浏览器隐私的问题。
- 由于网络应用程序非常复杂且可能生成大量可追踪的状态,因此对于私密浏览的定义并不明确。
- 浏览器根据用户需求和其他浏览器供应商的做法更新其私密浏览实现。
- 由于用户依赖私密浏览模式,他们对其期望更高…并且更多的实现缺陷浮出水面!
浏览器所谓的“私密浏览”是什么意思?
- 论文将此形式化为两个独立的威胁模型 攻击:
- 一个本地攻击者在浏览会话结束后拥有您的机器,并希望发现您访问过哪些网站。
- 一个网络攻击者入侵了您联系的网络服务器,并希望将您跨私密和/或正常会话进行关联。
- 如果两个攻击者合作,他们更容易识别用户。
- 例如:本地攻击者要求服务器检查服务器访问日志中的本地 IP 地址。
- 因此,对这两种攻击单独进行安全防护具有实际价值。
威胁 1:本地攻击者
- 假设: 攻击者在会话结束后控制用户的机器,并希望了解用户在私密浏览模式下访问了哪些网站。
- 安全目标: 攻击者不能了解这些网站!
- 非目标
- 不关心为未来的私密浏览会话实现隐私。
- 攻击者可能修改机器上的软件(例如安装键盘记录器)并跟踪未来的浏览活动。
- 这也是为什么我们假设攻击者在私密浏览开始之前无法访问机器。
- 隐藏使用私密浏览的事实。
- 通常被称为“合理否认”。
- 论文指出这很难实现,但没有解释原因。在后面的讲座中,我们将讨论一些潜在原因。
- 不关心为未来的私密浏览会话实现隐私。
私密会话可以泄漏哪些持久的客户端状态?(持久性指的是“存储在本地磁盘上”。)
- JavaScript 可访问的状态:Cookies,DOM 存储
- 浏览器缓存
- 访问地址的历史记录
- 配置状态:新的客户端证书,更新的保存密码数据库,书签
- 下载的文件
- 新插件/浏览器扩展
…以及:
- 所有私密浏览实现都试图防止持久泄漏到 1、2 和 3. 但是,4、5 和 6 在私密会话结束后通常仍然存在。
- 网络活动可能留下持久的证据–DNS 解析记录!
- 要解决这个问题,私密浏览模式需要在会话结束时刷新 DNS 缓存。然而,这很棘手,因为刷新缓存通常需要在您的机器上具有管理员权限(您希望浏览器具有管理员权限吗?)并删除所有 DNS 状态,而不是特定用户生成的状态。
- 在私密浏览期间,内存中的对象也可能被分页到磁盘上!
演示:
代码语言:javascript复制 Open Firefox in Private Browsing Mode
Visit http://pdos.csail.mit.edu/
sudo gcore $(pgrep firefox)
strings core.* | grep -i pdos
// -e l: Look for string using the
// character encoding 16-bit
// little-endian.
// -a: Scan all of the file.
// -t: Print the offset within
// the file.
数据生命周期是一个比私密浏览更广泛的问题!
- 例子:如果泄露了加密密钥或密码可能会有问题。参考链接
演示:
代码语言:javascript复制 cat memclear.c
cat secret.txt
make memclear
./memclear &
sudo gcore $(pgrep memclear)
strings core.* | grep secret
数据存在于哪里?
- 进程内存:堆,栈。
- 终端滚动回溯
- I/O 缓冲区,X 事件队列,DNS 缓存,代理服务器,…
- 语言运行时会复制数据(例如,在 Python 中的不可变字符串)
- 文件,文件备份,SQLite 数据库
- 交换文件,休眠文件
- 内核内存:
- IO 缓冲区:键盘,鼠标输入
- 释放的内存页面
- 网络数据包缓冲区
- 管道缓冲区包含进程间发送的数据
- 随机数生成器输入(包括再次输入按键)。
攻击者如何获取剩余数据的副本?
- 文件本身可能包含多个版本(例如,Word 曾支持此功能)。
- 如果程序在释放内存或程序关闭时不擦除内存,可能会泄漏信息:
- 例如:在旧版 Linux 内核中,当创建新目录时,最多可以泄漏 4 KB 的内核内存到磁盘。
- 例如:如果内核/VMM 不擦除内存页面,那么来自进程 X 的信息可能泄漏到使用 X 旧内存页面的进程 Y 中。
- 核心转储
- 直接访问机器
- 闪存 SSD 实现日志记录–它们不会立即擦除旧数据!
- 盗取的磁盘,或者只是处理旧磁盘 [参考链接: http://news.cnet.com/2100-1040-980824.html]
我们如何处理数据生命周期问题?
- 清空未使用的内存[会有一些性能降低]。
- 在难以清零的地方加密数据(例如,在 SSD 上)。
- 安全删除密钥意味着数据无法再解密!
- 例如:OpenBSD 交换使用加密,每次启动时生成新的加密密钥。
- 与磁盘 I/O 相比,加密的 CPU 成本是适度的。
威胁 2:网络攻击者
- 假设:
- 攻击者控制用户访问的网站。
- 攻击者无法控制用户的机器。
- 攻击者希望检测用户访问网站的情况。
- 安全目标:
- 攻击者无法识别用户。
- 攻击者无法确定用户是否使用私密浏览模式。
防御网络攻击者非常困难!
- 识别用户意味着什么?
- 同一用户从不同私密浏览会话中访问链接。
- 用户从私密浏览和公共浏览会话中访问链接。
- 识别用户的简单方法:IP 地址。
- 合理概率上,来自相同 IP 地址的请求是同一用户。
- 下一讲,我们将讨论 Tor。Tor 保护 TCP 连接源(即用户的 IP)的隐私。但是,Tor 并不能解决实现私密浏览的其他挑战。
- 即使用户使用 Tor,Web 服务器仍然可以通过分析她的浏览器运行时的独特特征来识别她!
浏览器指纹演示:
代码语言:javascript复制 - Open Chrome, go to http://panopticlick.eff.org/
- Open the same web site in private
browsing mode.
- 隐私的良好思考方式:用户的匿名集是什么?即,在哪个最大的用户集中,某个用户是无法区分的?
- Panopticlick 显示,对于大多数用户,此集合很小,因为用户倾向于具有唯一的本地设置,如字体、插件等。
- 网络攻击者如何确定您是否在使用私密浏览模式?
- 论文描述了基于链接颜色的历史嗅探攻击。
- 攻击者页面在 iframe 中加载 URL,然后创建到该 URL 的链接,并查看链接是否为紫色(私密会话不存储历史记录)。
- 由于浏览器不再向 JavaScript 公开链接颜色,此攻击不再有效![请参阅几堂课前讨论的历史嗅探攻击讨论。]
- 但是,攻击者可能有其他方法来判断您是否在使用私密模式。
- 例如:公共模式的 Cookie 无法被私密模式页面看到。因此,如果您在公共模式下访问页面,然后在私密模式下访问,页面可以检测到缺少预期的 Cookie。
- 论文描述了基于链接颜色的历史嗅探攻击。
方法
我们如何为私密浏览提供更强的保证?(暂时忽略 IP 地址隐私,或者假设用户使用 Tor。)
- 方法 1:虚拟机级隐私
- 计划:
- 每个私密浏览会话在单独的虚拟机中运行。
- 确保在私密浏览结束后删除虚拟机。
- 确保没有虚拟机状态最终出现在磁盘上[禁用分页?安全释放?]。
- 优势:
- 对本地攻击者和网络攻击者提供强有力的保证。
- 应用程序无需更改,只需安全删除虚拟机。
- 缺点:
- 为私密浏览启动单独的虚拟机是繁重的。
- 使用不便:用户更难保存私密浏览中的文件,使用书签等。
- 可用性和隐私之间存在固有的权衡!
- 计划:
- 方法 2:操作系统级隐私
- 计划: 在操作系统内核级别实现类似的保证。
- 一个进程可以在“隐私域”中运行,之后将被删除。
- 优势超过虚拟机:更轻量级。
- **相对于虚拟机的缺点:**更难正确实现,因为操作系统内核管理了大量状态。
- 计划: 在操作系统内核级别实现类似的保证。
是否有方法可以对使用这些方法的用户进行去匿名化?
- 也许虚拟机本身是独一无二的!因此,我们需要确保所有用户拥有类似的虚拟机。
- 这限制了用户可以定制虚拟机的程度。
- 也许 VMM 或主机计算机引入了一些独特性。
- 例如: TCP 指纹识别:TCP 协议允许实现设置一些参数(例如,初始数据包大小,初始 TTL)。
- 像 nmap 这样的工具向远程服务器发送精心制作的数据包;可以高度可能性地猜测远程操作系统!
- 用户仍然是共享的!因此,攻击者可能会:
- 检测用户的击键时序。
- 检测用户的写作风格。这被称为笔迹学。参考
浏览器为什么要实现自己的私密浏览支持?
- 主要原因是可部署性:用户不必在自定义虚拟机或操作系统中运行其浏览器。
- Native Client 有类似的动机。
- 另一个原因是可用性:私密模式中生成的某些类型的状态应该能够在会话结束后持续存在。(例如:下载的文件)。
- 这是一个危险的计划!浏览器是复杂的软件,因此很难找到架构中允许某些类型的状态(但不允许其他类型)持久存在的清晰界限。
我们如何对这些类型的状态进行分类?论文指出我们应该考虑是谁发起了状态更改(第 2.1 节)。
- 由网站发起,无用户交互: cookies,历史记录,缓存。
- 保持在会话内,会话结束时删除。
- 由网站发起,需要用户交互: 客户端证书,保存的密码。
- 不清楚什么是最佳策略;浏览器倾向于持久存储此状态,可能是因为用户必须明确授权该操作。
- 由用户发起: 书签,文件下载。
- 与上述相同:浏览器倾向于持久存储此状态,因为用户授权了该操作
- …但请注意,存储此状态可能会泄露用户使用私密浏览模式的事实!
- 例如: 在 Firefox 和 Chrome 中,书签存储在 SQLite 数据库中。在私密浏览模式下生成的书签将对
last_visit_count
等元数据有空值参考
- 例如: 在 Firefox 和 Chrome 中,书签存储在 SQLite 数据库中。在私密浏览模式下生成的书签将对
- 与会话无关: 浏览器更新,证书吊销列表更新。
- 将其视为在公共模式和私密模式之间共享的单个全局状态。
浏览器实际上实现了什么?
- 每个浏览器当然都是不同的。
- 此外,某些状态在一个方向上“泄露”,但在另一个方向上不会!私密模式和公共模式状态之间没有严格的分区。
问答:
- Q: 如果公共状态泄露到私密状态会发生什么?
- A: 网络攻击者更容易将私密会话与公共会话关联起来。
- 例如: 在公共模式下安装的客户端 SSL 证书可以识别私密模式中的用户。
- Q: 如果私密状态泄露到公共状态会发生什么?
- A: 这对于网络攻击者和本地攻击者都有帮助:观察公共会话的状态将会泄露关于私人会话的信息!
- Q: 用户在私密模式会话中时状态应该如何处理?
- A: 大多数浏览器允许状态在私密模式会话中持久存在(见表 3)。
- "否"表示网络攻击者可能能够检测到私密模式浏览!
- Q: 为什么允许在私密浏览模式下使用 cookies?
- 问: 对用户来说,在隐私浏览模式下能够创建临时会话很方便—浏览器将在私密会话结束时删除相关的 cookie。
- 问: 私密模式会话之间的状态应该如何处理?
- 答: 理想情况下,每个私密会话应该从零开始—如果状态在多个私密会话之间传递,这会增加用户被指纹识别的可能性!然而,由于某些类型的状态可以从私密到公共传递,某些类型的状态可以从公共到私密传递,因此某些类型的状态确实可以在私密模式会话之间持续存在。[例如:证书、下载的项目。]
- 因此,将每个私密模式会话视为与单个公共模式共享某些状态。
浏览器扩展
浏览器扩展和插件是特殊的。
- 它们是可以访问敏感状态的特权代码。
- 它们不受同源策略或其他浏览器安全检查的限制。
- 此外,它们通常是由浏览器供应商之外的人开发的!
- 因此,它们可能不了解私密模式的语义,或者可能错误地实现了预期的策略。
- 然而,插件可能在不久的将来会灭绝!HTML5 提供了新功能,为以前需要 Flash、小程序、Silverlight 等的功能提供了本机支持。参考
- 多媒体:
<video>
,<audio>
- 图形:
<canvas>
WebGL - 离线存储:DOM 存储
- 网络:Web sockets,CORS
- 多媒体:
当前的私密浏览模式
该论文是在 2010 年撰写的—私密浏览的当前状态如何?
- 仍然很难正确实现私密浏览!
- 例如: 2014 年 1 月的 Firefox 漏洞修复:pdf.js 扩展允许公共 cookie 泄漏到私密模式的 HTTP 获取中。参考
- 该扩展没有检查私密浏览模式是否已启用!
- 例如: 2011 年的 Firefox 漏洞:如果您在隐私浏览模式下访问页面,然后关闭窗口,您可以转到 about:memory 并找到关于您所关闭的窗口的信息(例如,about:memory 将列出窗口的 URL)。参考
- 问题在于窗口对象是惰性垃圾回收的,因此关闭窗口不会强制窗口进行同步垃圾回收。
- 当潜在解决方案比最初预期的更复杂时,该漏洞被“降级处理”;作为回应,一位开发者说:“这听起来很令人难过。这几乎可以破坏诸如 sessionstore 忘记关闭的私密窗口等功能的目的。”
- 例如: 2014 年 1 月的 Firefox 漏洞修复:pdf.js 扩展允许公共 cookie 泄漏到私密模式的 HTTP 获取中。参考
- 现成的取证工具可以找到私密浏览器会话的证据。
- 例如: Magnet 的 Internet Evidence Finder [1],[2],可以找到 IE、Chrome 和 Firefox 的私密会话痕迹。
- 在私密会话期间,IE 将对象存储在文件系统中。这些对象在私密会话关闭时被删除,但存储空间并未被擦除,因此私人数据仍然存在于未分配的磁盘空间中。
- Chrome 和 Firefox 在私密浏览期间使用内存中的 SQLite 数据库,因此在文件系统中留下较少的痕迹。然而,像所有浏览器一样,它们在页面文件中留下痕迹。
- 例如: Magnet 的 Internet Evidence Finder [1],[2],可以找到 IE、Chrome 和 Firefox 的私密会话痕迹。
Tor
注意: 这些讲座笔记是从 2014 年 6.858 课程网站上发布的笔记中稍作修改的。
论文的目标是什么(或 Tor 的目标是什么)?
- 为了客户端的匿名性,他们想要连接到互联网上的服务器。
- 对于希望为用户提供服务的服务器的匿名性。
- 什么是匿名性?
- 对手无法确定哪些用户正在与哪些服务器通信。
- 对手(最有可能)知道用户,服务器是通过 Tor 进行通信的。
- 换句话说,Tor 并不是为了防止对手找到 Tor 用户而设计的。
如何实现匿名性?
- 必须加密要匿名的人的流量。
- 否则,对手会查看数据包并弄清楚发生了什么。
- 但加密并不足够:仍然可以追踪加密数据包的去向。
- 将一个用户的流量与其他用户的流量混合(或“掩盖流量”)。
- 一个用户的匿名性需要有许多其他像第一个用户一样的用户。
- 如果所有其他用户只运行 BitTorrent,那么维基百科用户很容易被发现。
- 如果所有其他用户使用 Firefox,那么 Chrome 用户很容易被发现。
- …
- 对手将无法确定哪个用户发起了什么连接。
- 混合组件必须更改数据包(例如,加密/解密)。
- 否则,可以查找相同数据包稍后出现的位置。
- 因此,方法是:通过加密/解密的中间人中继流量。
为什么我们需要多个节点?
- 可扩展性:处理比单个节点更多的流量。
- 妥协:攻击者了解有关受损节点的直接客户端的信息。
- 有许多独立节点,这只影响了一小部分流量。
- 使用洋葱路由,攻击者必须妥协链中的所有节点。
- 流量分析:攻击者可以相关联传入/传出的流量。
- 可以查看数据包之间的时间间隔或数据包的数量。
- 链接使时间/数据量分析攻击更难实施。
- 攻击者仍然能够成功吗?
- 是的,如果他们观察或者妥协足够多的节点。
- 例如,可能足以观察第一个和最后一个节点。
- 攻击者还可以注入时间信息(通过延迟数据包)进行分析。
主要思想:洋葱路由
- 网络中的洋葱路由器(ORs)的网格。
- 假设:客户端知道所有 ORs 的公钥。
- 客户端选择通过这个网络的某条路径。
- 洋葱路由的天真草人(不完全是 Tor):
- 客户端依次在路径中的每个 OR 的公钥中加密消息。
- 将消息发送到路径中的第一个 OR,该 OR 解密并中继,依此类推。
- “出口节点”(路径中的最后一个 OR)将数据发送到真实网络中。
- 为什么这是一个好的设计?
- 每个 OR 都知道前一个和下一个跳跃,而不知道最终源或目的地。
- 通过两个 ORs,妥协一个 OR 并不会破坏匿名性。
在哪个级别应该中继事物?
- 可以在任何级别进行–IP 数据包,TCP 连接,应用级别(HTTP)
- 优势/劣势是什么?
- 低级别(IP):更一般,更少的应用程序更改,适用于更多应用程序。
- 更高级别(TCP,HTTP):更高效(单个 TCP 帧的开销,而不是存储单个 TCP 帧的多个 IP 帧的开销),更匿名。
- Tor 做了什么?
- 使用 SOCKS 进行 TCP 级中继,拦截 libc 调用。
- 效率的例子:不需要 TCP 流量控制,Tor 进行重传
- 丢失通用性的例子:UDP 无法工作,无法进行路由跟踪,…
- Tor 如何处理 DNS,如果不支持 UDP?
- SOCKS 可以捕获目的地的主机名,而不仅仅是 IP 地址
- 出口节点执行 DNS 查找,建立 TCP 连接
- 丢失在较低层的匿名性的例子?
- 如果我们使用 IP,将泄漏大量 TCP 信息(序列号,时间戳)
- 如果我们使用 TCP,将泄漏各种 HTTP 头和 cookie。
- 如果我们使用 HTTP,可以通过 Javascript,Flash 等违反匿名性。
- Javascript 环境中有许多可识别的特征。
- 浏览器版本,历史嗅探,本地网络地址/服务器…
- “协议规范化”:在更高级别协议中修复所有自由度。
- 在实践中很难做到;特定于应用程序的代理很有用(例如,Privoxy)。
- 浏览器“识别”的演示:https://panopticlick.eff.org/
Tor 设计
- OR 的网格:每个 OR 通过 SSL/TLS 连接到其他每个 OR。
- 不需要 CA 签名的 SSL/TLS 证书。
- Tor 有自己的公钥检查计划,使用目录服务器。
- OR 主要由志愿者运行:例如,MIT 运行几个。
- 终端用户运行实现 SOCKS 的洋葱代理(OP)。
- OR 有两个公钥:身份密钥和洋葱密钥。
- 身份密钥在目录中注册,签署 OR 状态。
- Onion 密钥由 OP 用于连接 OR,建立电路。
- 客户端从目录下载 OR 列表。
- 选择一系列 OR 形成电路,依次联系每个 OR。
- 客户端建立电路是昂贵的。- 为什么要这样做?
- 任何单个服务器可能被 compromise,无法信任它。
- 无法避免信任客户端机器。
- 为什么我们需要洋葱密钥以及身份密钥?
- 可能能够保护身份密钥免受长期损害。
- 每个 OR 使用身份密钥签署其当前的洋葱密钥。
- Tor 为什么需要目录?
- 需要有人批准 OR。
- 否则攻击者可以创建许多 OR,监视流量。
- 目录是否会损害匿名性?
- 不,不需要在线查询。
- 如果一个目录被 compromise 了怎么办?
- 客户端需要大多数目录同意。
- 如果许多目录被 compromise 了怎么办?
- 攻击者可以注入许多 OR,监视流量。
- 如果目录不同步怎么办?
- 攻击者可能根据目录信息缩小用户身份范围。
- 看到一组目录消息的用户将使用特定的 OR。
- 需要有人批准 OR。
术语:电路和流。
- 电路:客户端建立的通过 OR 列表的路径。
- 电路存在一段时间(也许几分钟)。
- 定期打开新的电路以防止攻击。
- 流实际上是一个 TCP 连接。
- 许多流在同一电路上运行(每个具有单独的流 ID)。
- 流是一个重要的优化:无需重建电路。
- Tor 为什么需要电路?
- 如果电路存在时间很长会出现什么问题?
- 对手可能将多个流关联到一个电路中。
- 将单个用户的连接与不同站点联系起来,破坏匿名性。
Tor 电路
- 电路是 OR 序列,以及共享的(对称 AES)密钥。
- ORs
c_1, c_2, .., c_n
- 键
k_1, k_2, .., k_n
- ORs
- 单元格格式:
-
--------- --------------- -----------
-
| 电路 | 控制/中继 | - 数据 |
-
--------- --------------- -----------
-
2 字节 1 字节 509 字节
-
- 将"Circuit"和"Control/Relay"字段视为链路层头部。
- 电路 ID 是每对 OR 之间的。
- 用于在 OR 之间的同一 TLS 连接上多路复用许多电路。
- 控制消息是"链路本地的":仅发送给直接邻居。
- 中继消息是"端到端的":沿着电路中继。
- 为什么所有流量都是固定大小的单元格?
- 使流量分析更加困难。
- 控制命令是什么?
- 填充:保持活动或链路填充。
- create/created/destroy:创建和销毁电路。
- 中继数据包中有哪些中继命令(DATA 中有什么)?
- 如果中继数据包目标是当前节点:
-
---------- -------- ----- ----- -----------
-
| StreamID | Digest | Len | CMD | RelayData |
-
---------- -------- ----- ----- -----------
-
2 字节 6 字节 2 1 498 字节
- 如果中继数据包目标是另一个节点:
-
-------------------------------------------
-
| 加密的、不透明的数据 |
-
-------------------------------------------
-
509 字节
- TCP 数据的 CMD 字段是"中继数据"。
- 其他值如"relay begin"等用于建立流。
OP 如何通过电路发送数据?
- 如上所述组成中继数据包(尚未加密)。
- 计算有效的校验和(摘要)。
- 摘要基于应解密数据包的目标 OR。
- 哈希是通过某个键的函数和与该 OR 交换的所有消息进行的。
- 防止重放攻击和主动攻击
- 摘要的前 2 个字节为零,其他 4 个字节来自哈希。
- 使用
AES(k_n)
加密,然后使用AES(k_{n-1}), .., AES(k_1)
加密。 - 发送加密单元格到第一个 OR(
c_1
)。- (OP 通过电路接收数据的逆过程。)
OR 如何处理中继数据包?
- 如果来自 OP 的方向,解密并远离 OP 转发。
- 如果不是来自 OP 的方向,加密并转发至 OP
OR 如何知道中继数据包是否适用于它?
- 验证校验和:如果匹配,则很可能适用于当前 OR。
- 优化:摘要的前 2 个字节应为零。
- 如果前两个字节不为零,则可以跳过哈希:不是我们的数据包。
- 如果校验和不匹配,则不适用于此 OR,继续中继。
- 美好的特性:
- 数据包大小与路径长度无关。
- 只有最后一个 OR 知道目的地。
如何建立一个新的流?
- OP 通过电路发送"relay begin"。- 包含目标主机名、端口。
- 谁选择流 ID?- OP 可以在其电路中选择任意流 ID。
什么是"漏水管"拓扑?
- OP 可以向其电路中的任何 OR 发送中继消息(不仅仅是最后一个 OR)。
- 可以通过任何 OR 构建流(即,TCP 连接),以防止流量分析。
初始化电路
- OP 选择要用于其电路的 OR 序列。
- 为什么要让 OP 这样做?- 抵抗其他 OR“转移”电路。
- 连接到第一个 OR,发出“创建”操作以创建电路。
- 创建包括 DH 密钥交换消息。
- 创建响应包括 DH 密钥交换回复。
- 密钥交换协议:
- [OP,OR 同意素数 p,生成器 g]
- OP 选择随机 x。
- OP 发送
E_{PK_OR}(g^x)
。 - OR 选择随机 y。
- OR 计算
K=g^xy
。 - OR 回复
g^y, H(K || "handshake")
。 - OP 计算
K=g^xy
。
- 我们如何在这里验证各方身份?
- 第一个 DH 消息使用 OR 的洋葱密钥加密。
- DH 响应中密钥的哈希证明向客户端证明正确的 OR 解密了消息。
- 服务器不验证客户端-匿名性!
- 前向保密:是什么?如何实现?
- 密钥新鲜度:为什么?如何实现?
- 谁选择电路 ID?
- TLS 连接的客户端端点(而不是整个电路的 OP)。
- 每个电路对于其穿越的每个链接具有不同的电路 ID。
- 控制数据包中的数据是什么?
- 控制操作(创建,销毁)或响应(例如,已创建)。
- 参数(例如,DH 密钥交换数据)。
- 对于每个后续 OR,OP 通过电路发送“中继扩展”消息。
- 在“中继扩展”单元中包含相同的 DH 密钥交换消息。
- 在电路结束时,“中继扩展”转变为“创建”。
- 客户端最终获得每个电路中每个 OR 的共享(对称 AES)密钥。
- Tor 为什么有单独的控制单元和中继单元?
- 确保单元始终具有固定大小。
- 旧电路中的最后一个 OR 需要知道新 OR 和电路 ID。
每个通过 OR 的电路保留哪些状态?
- 电路中两个方向(从 OP 到 OR)的电路 ID 和相邻 OR。
- 与此电路和此 OR 的 OP 共享密钥。
- 每个电路的 SHA-1 状态。
我们能否避免在网络中存储所有这些状态?
- 没有每个单元中的可变长度路径描述符。
- 出口节点同样需要路径描述符才能知道如何发送回去。
- 中间节点需要执行公钥加密(昂贵)。
Tor 为什么需要出口策略?
- 防止滥用(例如,匿名发送垃圾邮件)。
- 出口策略类似于防火墙规则(例如,不能连接到端口 25)。
- 每个出口节点在打开新连接时检查出口策略。
- 为什么在目录中发布出口策略,以及其他节点信息?
- 不用于强制执行。
- OP 需要知道哪些出口节点可能有效。
如果 Tor 不进行完整性检查会怎样?
- 需要完整性以防止标记攻击。
- 攻击者入侵内部节点,损坏数据包。
- 损坏的数据包最终会被发送出去,可以观察它们的去向。
Tor 如何防止重放攻击?
- 每个校验和实际上是 OP 和 OR 之间所有先前单元的校验和。
- 再次发送相同数据的校验和将不同。
- 运行良好,因为底层传输是可靠的(SSL/TLS 在 TCP 上)。
匿名服务
- 隐藏服务由公钥命名(伪 DNS 名称“publickey.onion”)。
- 为什么要在介绍点和会面点之间分开?
- 避免在介绍点上放置流量负载。
- 避免介绍点传输已知非法数据。
- 分割可以防止这两个问题。
- Bob(服务)有一个介绍点(IP)。
- Alice 选择一个会面点(RP),告诉 Bob 的 IP 关于 RP。
- 介绍点不中继数据。
- 会面点不知道它正在中继的数据是什么
- 为什么 Bob 要连接回 Alice?
- 准入控制,将负载分散到许多会面点。
- 什么是会面点 cookie?-让 Bob 向 Alice 的 RP 证明它是 Bob。
- 什么是授权 cookie?
- 一些可能会促使 Bob 回复的东西,否则他不会回复。
- 或许是大多数人不知道的秘密词语。
- 限制对 Bob 服务器的 DoS 攻击(只需发送许多 cookie)。
- 存储在主机名中:cookie.pubkey.onion。
- 最终状态:两个电路连接到 RP,之间有一个流连接。
- RP 从一个电路的流中获取中继单元,并
- 将它们发送到另一个电路中的流中。
- 使用 Alice 和 Bob 之间共享的密钥(DH)加密桥接数据。
- 每个人都可以控制自己的匿名级别。
- 两个电路的完整路径都不知道。
使用 Tor 时可能会遇到的潜在问题?
- 应用层泄漏(Javascript,HTTP 头,DNS,…)
- 使用应用级代理(例如,Privoxy 剥离许多 HTTP 头)。
- 基于 Tor 客户端行为的指纹识别(新电路打开的频率)。
- 时间/量分析(部分防御是运行自己的 Tor OR)。
- 对网站进行指纹识别:流行网站的请求次数和文件大小。
- 固定大小单元的量化有所帮助。
- 恶意 OR:加入网络,广告大量带宽,开放出口政策。
运行 OR 的好处/风险?
好处:
- 更多的匿名性
风险:
- 资源使用
- 在线攻击(DoS,入侵,…)
- 离线攻击(例如,机器被执法部门扣押)
阻止 Tor 有多难?
- 从目录中找到 OR IP 列表,阻止所有流量到它们。
- 如何防御这种攻击?
- 向不同的客户端透露不同的 OR?
- 允许基于使用的 OR 对客户端进行指纹识别。
- 保持一些未列出的 OR?
- 只将未列出的 OR 用作第一跳,以避免指纹识别。
- Tor 有“桥接”节点的概念,这是一个未列出的 OR。
- 如何找到这些未列出的“桥接”OR?
- 希望合法用户找到它们,但不让对手枚举它们。
- Tor 采取的方法:特殊的桥接目录。
- 向每个 IP(通过 HTTP)或电子邮件地址(通过电子邮件)透露 3 个桥接。
- 仅在 24 小时后向相同客户端地址透露新的桥接。
- 可以按 IP 限制速率,找到尝试枚举桥接数据库的尝试等。
- 对于电子邮件,对手更容易创建虚假身份(电子邮件地址)。
- Tor 信任 3 个邮件提供商来限制注册(gmail,yahoo,mit)。
你会使用 Tor 吗?它适用于哪些应用程序?
- 可能对所有流量使用速度太慢(高延迟)。
- 但不幸的是,这意味着只有敏感流量会通过 Tor 传输。
- 可能存在可信攻击,因此对抗非常强大的对手不是很好。
- 或许是避免拒绝服务攻击的好方法(即,转移到 Tor 上)。
- 据说,谷歌使用 Tor 来检查服务器是否特殊处理谷歌的 IP 地址。
Tor 有多活跃?
- 现在比论文描述的使用更加活跃。
- ~3000 个公共 ORs,~1000 个出口节点,~1000 个桥接节点,~2GB/s 的 OR 带宽。
- 8-9 (?) 个目录服务器,约 1600 个目录镜像。
- 困难问题:分发入口点 IP 地址,批准 ORs,…
- 有些 BitTorrent 使用,但并不压倒性:主要是因为对于大文件来说太慢了。
另一种方法:DC-nets(“用餐密码学家网络”)。
- N 个参与者,但假设只有一个发送者(不知道是谁)。
- 每对参与者共享一个秘密比特位。
- 要传输“0”比特位,发送所有秘密的异或值。- 否则,发送相反的值。
- 所有传输都是公开的:为了恢复比特位,对所有人的传输进行异或运算。
- 可以建立发送多个比特位,使用冲突检测协议等。
- 在性能方面代价高昂,但提供比 Tor 更强大的安全性。
- 查看 Dissent OSDI 2012 论文,了解基于 DCnet 的系统的更多细节。
参考:
- Tor 项目指标
- Tor 共识健康
- 部署低延迟匿名性的挑战
- 一个抗阻塞匿名系统的设计
- 用餐密码学家问题
- 数字中的异议:使强大的匿名性扩展
Android 安全
注意: 这些讲座笔记略有修改,来自 2014 年 6.858 课程网站上发布的内容。
为什么选择这篇论文?
- 真实系统,被广泛使用。
- 谨慎的安全设计(比 Web 或桌面应用程序更重要)。
- 原则=应用程序(而不是用户)
- 策略与代码(清单)分离
- 一些问题是不可避免的,并且看到问题出现的地方是有启发性的。
- 但也有趣的是看如何设计一个合理的安全计划。
威胁模型
- 目标: 任何人都可以编写任何人都可以安装的应用程序
- 威胁:
- 应用程序可能存在错误
- 应用程序可能是恶意的
CVE 数据库
-
www.cvedetails.com/vulnerability-list/vendor*id-1224/product*id-19997/Google-Android.html
- 一些错误但不是压倒性的—安全计划有效吗?
- 缓冲区溢出(仍然发生…)
- 当然,Android 运行在 Linux 上,这也包括 Linux 内核问题
总体计划
- 首先了解 Android 应用程序的外观和工作原理。
- 然后讨论安全机制和策略。
Android 应用程序是什么样子的?
- 四种组件类型:
- 活动: 应用程序的 UI 组件,通常每个“屏幕”一个活动。
- 服务: 后台处理,可以被其他组件调用。
- 内容提供程序: 可被其他组件访问的 SQL 数据库。
- 广播接收器: 接收来自其他组件的广播通知。
- 每个应用程序还有私有文件存储。
- 应用程序通常用 Java 编写。
- 运行在 Linux 内核 Android“平台”上(稍后会介绍)。
- 应用程序还有一个声明其权限的清单(稍后)。
- 整个应用程序由开发者签名。
活动:可以在屏幕上绘制,获取用户输入等。
- 一次只有一个活动在运行。
- 帮助用户推理输入的安全性。
- 如果用户正在运行银行应用程序(活动),则没有其他活动获取用户的输入。
意图:Android 中的基本消息原语。
- 代表应用程序意图做某事/与另一个组件交互。
意图字段:
- 组件:将请求路由到的组件名称(只是一个字符串)。
- 例如,
com.google.someapp/ComponentName
- 例如,
- 操作:此消息的操作码(只是一个字符串)。
- 例如,
android.intent.action.MAIN
,android.intent.action.DIAL
,…
- 例如,
- 数据:用于动作的数据的 URI(只是一个字符串)。
- 例如,
tel:16172536005
,content://contacts/people/1
(用于拨号)。 - 还包括数据的 MIME 类型。
- 例如,
- 类别:用于查找发送意图的过滤机制。
- 例如,
android.intent.category.BROWSABLE
表示可以从浏览器调用,用于动作android.intent.action.VIEW
,该动作查看数据中的 URI。
- 例如,
- 显式意图:指定组件名称。
- 隐式意图:没有组件名称,因此系统必须找出。
- 查看动作,数据,类别。
- 如果有多个组件匹配,也可以询问用户要使用哪个应用程序。
- 例如,用户点击地址 - 要打开哪个地图应用程序?
对服务的 RPC
- 初始与服务的通信通过发送意图进行。
- 服务还可以为客户端定义一个 RPC 协议。
- 比每次发送意图更有效。
- 客户端将连接“绑定”到服务。
网络 - 访问互联网。
- 与任何其他 Linux 系统中一样工作。
- 应用程序可以直接使用套接字,也可以通过 Java 的网络库。
为什么我们需要一个新的应用程序模型?(或者,现有模型有什么问题?)
- 桌面应用程序:
- – 应用程序之间的隔离不够。
- – 每个应用程序都拥有完整的特权,任何一个恶意应用程序都可以接管。
- 应用程序可以轻松互相交互,共享文件。
- 用户可以为每个任务选择应用程序(电子邮件应用程序、图像查看器等)。
- 基于 Web/浏览器的应用程序:
- 无需安装应用程序或担心本地状态。
- – 在典型模型中需要服务器(离线使用困难)。
- – 应用程序之间的互动有限。
- – 存在的互动通常是硬编码到特定的 URL。
- 例如,链接到联系管理器应用程序的 URL:用户无法选择新的。
- 越来越好:尝试解决此问题的“Web 意图”。
- – 纯客户端应用程序的功能有些受限。
- 越来越好:相机、位置信息、本地存储、工作线程等。
Android 访问控制
Android 的应用程序模型如何处理应用程序互动、用户选择应用程序?
- 主要基于意图。
- 如果多个应用程序可以执行一个操作,发送隐式意图。
- Android 框架决定哪个应用程序获得意图;可以询问用户。
Android 的应用程序模型如何处理应用程序隔离?
- 每个应用程序的进程在 Linux 中运行在单独的 UID 下。
- 例外:一个开发者可以将多个应用程序捆绑到一个 UID 中。
- 每个应用程序都有自己的 Java 运行时(但这主要是按照惯例)。
- Java 解释器不受信任,甚至不是必需的;内核强制执行隔离。
每个应用程序 UID 有什么好处?
- 一个应用程序不能直接操作另一个应用程序的进程、文件。
- 每个应用程序都有私有目录(
/data/data/appname
)。- 存储首选项、内容提供程序的 sqlite 数据库、缓存文件等。
UID 隔离缺少什么:对共享资源的访问控制。
- 网络访问。
- 可移动的 sd 卡。
- 设备(相机、指南针等)。
- 意图:谁可以发送,什么意图,发送给谁?
- 我们还需要以某种方式确定所有这些的策略。
首先,机制:Android 如何控制对上述所有内容的访问?
- 网络访问:GIDs。
- 特殊的组 ID 定义了应用程序可以与网络通信的内容。
- GID
AID_NET_BT_ADMIN (3001)
: 可以创建低级蓝牙套接字 - GID
AID_NET_BT (3002)
: 可以创建蓝牙套接字 - GID
AID_INET (3003)
: 可以创建 IP 套接字 - GID
AID_NET_RAW (3004)
: 可以创建原始套接字 - GID
AID_NET_ADMIN (3005)
: 可以更改网络配置(ifconfig,…)
- GID
- 需要内核更改才能实现这一点。
- 每个应用程序根据其特权获得这些组 ID 的子集。
- 没有对网络通信进行更精细的控制。
- 例如,可以想象按 IP 地址或按来源类似的策略。
- 特殊的组 ID 定义了应用程序可以与网络通信的内容。
- 访问可移动 SD 卡。
- 为什么不使用文件系统权限?
- 希望在 SD 卡上使用 FAT 文件系统,以允许在其他设备上访问。
- FAT 文件系统没有文件所有权、权限等概念。
- 内核将所有 SD 卡文件视为特殊组 sdcard_rw(1015)拥有。
- 应该访问 SD 卡的应用程序在其组列表中具有此 GID。
- 在整个 SD 卡内没有更精细的隔离。
- 为什么不使用文件系统权限?
- 设备。
- 设备文件(
/dev/camera
、/dev/compass
等)由特殊组拥有。 - 应用程序在其组列表中以适当的组运行。
- 设备文件(
- 意图。
- 所有意图都经过单个可信的“参考监视器”路由。
- 运行在 system_server 进程中。
- 参考监视器执行意图解析(将意图发送到哪里?),
- 用于隐式意图。
[ref: ActivityStack.startActivityMayWait]
- 用于隐式意图。
- 参考监视器检查权限,基于意图和发送者。
[ref: ActivityStack.startActivityLocked]
- 将意图路由到适当的应用程序进程,或启动一个新的进程。
- 为什么不只使用意图来处理一切,而不是使用特殊组?
- 效率:希望直接访问相机、网络、SD 卡文件。
- 通过意图发送所有内容可能会带来重大开销。
参考监视器如何决定是否允许一个意图?
- 分配给应用程序和组件的“标签”。
- 每个标签都是一个自由格式的字符串。
- 通常以 Java 风格的包名称编写,以确保唯一性。
- 例如,
com.android.phone.DIALPERM
。
- 每个组件都有一个保护它的单个标签。
- 对该组件的任何意图必须由具有该标签的应用程序发送。
- 例如,电话拨号服务标记为
...DIALPERM
。 - 对于内容提供程序,有两个标签:一个用于读取,一个用于写入。
- 应用程序有一个授权使用的标签列表。
- 例如,如果应用程序可以拨打电话,则
...DIALPERM
在其标签集中。
- 例如,如果应用程序可以拨打电话,则
- 其他权限(网络、设备、SD 卡)映射到特殊的标签字符串。
- 例如,android.permission.INTERNET 被翻译为应用程序在 GID 3003 下运行。
应用程序如何获得一组特定标签的权限?
- 每个应用程序都有一个声明其所需权限(标签)的清单。
- 还声明了应该保护每个组件的标签。
- 当应用程序安装时,Android 系统会询问用户是否允许安装应用程序。
- 提供应用程序正在请求的权限列表。
曾经,Android 允许用户设置细粒度的权限选择。
- Android 4.3 引入了“权限管理器”。
- 显然,这在 Android 4.4 中被移除了。
- 可能的原因:开发人员希望对事物有可预测的访问。
谁定义权限?
- 应用程序自己定义权限(回想:只是自由格式的字符串)。
- Android 系统为内置资源(相机、网络等)定义权限。
- 可以使用 ‘adb shell pm list permissions -g’ 列出。
- 内置应用程序为其提供的服务定义权限。
- 例如,读取/写入联系人、发送短信等。
- 定义权限意味着指定:
- 权限的用户可见名称。
- 用户的权限描述。
- 将权限分组到一些类别中(花费、私人数据等)。
- 权限类型:“正常”、“危险”和“签名”。
三种权限类型的含义是什么?
- 正常: 可能会让应用程序烦扰用户,但不会造成严重后果的良性权限。 例如,SET_WALLPAPER。 比较 (pm list permissions -g -d) 和 (pm list permissions -g) 系统不会询问用户有关“正常”权限。 为什么要有这些权限? 可以在真正感兴趣时进行审查。 最小权限原则,如果应用程序以后被破坏。
- 危险:
- 可能允许应用程序执行危险操作。
- 例如,访问互联网、访问联系信息等。
- 签名:
- 只能授予由同一开发人员签名的应用程序。
- 想要强制使用 HTTPS:希望防止用户意外泄露。
为什么在引用监视器中进行此检查,而不是在每个应用程序中?
- 便利性,以防程序员忘记。
- 可以在应用程序端的库中执行。
- 根据权限可能将意图路由到不同的组件。
- 不想发送一个意图给组件 A,而另一个组件 B 却愿意接受它。
- 强制访问控制(MAC):权限与代码分开指定。
- 附注:烦恼,MAC 是一个多义词缩写。
- 媒体访问控制 – 以太网中的 MAC 地址。
- 消息认证码 – Kerberos v4 缺少的东西。
- 希望了解系统的安全属性而不查看代码。
- 附注:烦恼,MAC 是一个多义词缩写。
- 对比:Unix 中的自主访问控制(DAC)。
- 每个应用程序都可以在文件上设置自己的权限。
- 权限可以随时间由应用程序更改。
- 看当前文件权限无法准确预测会发生什么。
- 应用程序也可以执行自己的检查。
[ref: checkCallingPermission()]
- 有点破坏了 MAC 模型:不能只看清单。
- 有必要,因为一个服务可能导出不同的 RPC 函数,
- 想要为每个权限设置不同级别的保护。
- 引用监视器只检查客户端是否可以访问整个服务。
谁可以注册接收意图?
- 任何应用程序都可以指定要接收具有任意参数的意图。
- 例如,可以在意图过滤器中创建活动(在清单中):
示例:
代码语言:javascript复制 <intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="http" android:host="web.mit.edu" />
</intent-filter>
- 这是一个问题吗?
- 为什么或为什么不?
- 每当用户点击链接到 http://web.mit.edu/ 时,系统会提示用户。
- 只有“顶层”用户点击转换为意图,而不是网页组件。
- 如果提示用户可能会没问题。
- 即使如此,如果您唯一的地图应用程序是“不好的”:窃取发送给它的地址?
- 对于广播意图来说并不是很好,因为会发送给所有可能的接收者。
控制广播意图的分发。
- 在文档的示例中,希望
FRIEND_NEAR
意图不被所有人披露。 - 解决方案:发送方在发送广播意图时可以指定额外的权限标签。
- 参考监视器只将此意图发送给具有该标签的接收方。
如何验证意图的来源?
- 通常在接收组件上使用权限标签。
- 只要发送方具有正确的权限,就不一定关心发送方是谁。
- 结果应用程序经常忘记在广播接收器上设置权限限制。
- 2011 年 Usenix 安全论文:“权限再委托攻击”。
- 例如,可以创建一个永远响铃和震动的闹钟。
- 例如,可以向设置广播接收器发送消息以切换 wifi 等。
- 安卓中的一个解决方案:“受保护的广播”(不完整,但是…)
- 参考监视器特殊处理一些意图操作(例如,系统启动)。
- 只有系统进程可以发送那些广播意图。
发送方是否可以依赖名称将意图路由到特定组件?
- 更广泛地说,安卓如何验证名称?(应用程序名称,权限名称。)
- 没有一般计划,只是先到先得。
- 系统名称(应用程序,权限等)在这个模型中获胜。
- 其他应用程序可能会被先到的恶意应用程序抢占。
- 可以通过使用应用程序的名称向恶意应用程序发送敏感数据。
- 可以通过查看发送者名称信任恶意应用程序的意图。
- 可以通过使用恶意应用程序的权限名称设置宽松权限。
如果两个应用程序定义了相同的权限名称会发生什么?
- 先到先得。
- 恶意应用程序可以将一些重要权限名称注册为"正常"。
- 任何应用程序(包括恶意应用程序)现在都可以获得此权限。
- 其他依赖此权限的应用程序将容易受到恶意应用程序的攻击。
- 即使受害应用程序定义了自己的权限并且是唯一使用它的应用程序。(例如,签名权限。)
- 可能更好的做法:如果权限已经定义,则拒绝安装应用程序。
- 允许应用程序假设其自己的权限已经正确定义。
- 仍然不允许应用程序假设其他应用程序/权限名称的任何内容。
如果应用程序名称没有经过验证,为什么应用程序需要签名?
- 代表开发者。
- 对 CA 没有真正的要求。
- 帮助安卓回答三个问题:
- 这个新版本的应用程序是否来自与旧版本相同的开发者?(如果是,可以升级。)
- 这两个应用程序是否来自同一开发者?(如果是,可以请求相同 UID。)
- 应用程序是否来自定义权限的相同开发者?(如果是,可以获得访问签名级别权限。)
如何给另一个应用程序临时权限?
- URI 委托。
- URI 读/写访问的能力式委托。
- 系统通过文字字符串 URI 跟踪委托访问。
- 例如,
content://gmail/attachment/7
- 例如,
- 必须记得撤销委托访问!
- 例如,URI 可能表示稍后的另一条记录…
[ref: grantUriPermission(), revokeUriPermission()]
- 例如,URI 可能表示稍后的另一条记录…
- 参考监视器将授予的 URI 保留在内存中。
[ref: ActivityManagerService.mGrantedUriPermissions]
- 授权是短暂的,只持续到重新启动。
- 待定意图。
- 用例:从闹钟/时间服务回调到您的应用程序。
- system_server 在内存中跟踪挂起的意图;短暂的。[参考:PendingIntentRecord.java]
- 撤销问题,与 URI 委托一样。“破坏”了 MAC 模型:无法完全从清单中推理出所有安全性。
应用程序存储在哪里?
- 两个选项:内部手机存储器或 SD 卡。
- 内部存储器始终由 Android 控制,因此可以假设它是安全的。
- 在 SD 卡上安装应用程序更加复杂,但由于空间原因更可取。
- 威胁模型:
- 担心恶意应用程序修改 SD 卡数据。
- 担心恶意用户复制付费应用程序。
- SD 卡使用 FAT 文件系统,没有文件权限。
- 方法:使用每部手机的随机密钥对应用代码进行加密/认证。
- 密钥存储在手机的内部闪存中,对应手机唯一。
- 威胁模型:
Android“平台”的安全性有多高?
- TCB:内核 任何以 root 身份运行的东西。
- 优于桌面应用程序:
- 大多数应用程序不属于 TCB 的一部分。
- 作为 root 运行的东西要少得多。
- 一些漏洞在实践中显现。
- Linux 内核或 setuid-root 二进制文件中的错误允许应用程序获取 root 权限。
- 如何做得更好?
- 系统调用过滤/ seccomp 使利用内核漏洞变得更加困难?
- 不清楚。
- 用户无意中安装具有危险权限的恶意软件应用程序。
- 实际常见的恶意软件:向高价号码发送短信。
- 攻击者通过部署此类恶意软件直接获得金钱。
- 用户为什么会犯这样的错误?
- 一个原因:某些权限对于平凡任务和敏感任务都是必要的。
- 例如,访问电话状态/身份需要获取唯一设备 ID。
- 导致不必要请求危险权限,使用户麻木不仁。
- 另一个原因:应用程序提前要求权限“以防万一”。
- 例如,可能以后需要它们,但更改权限需要手动更新。
- 另一个原因:无法拒绝某些权限。
- 另一个原因:包含恶意软件的现有 Android 应用程序的副本。
- 如何修复?
- 找到允许更多“非危险”权限而无需询问用户的方法。
- 允许用户有选择地禁用某些权限。(有关此方面的一些研究工作,请参见下面的参考资料。)
- 静态/运行时分析和审计–现在由 Google 实施。
- 寻找现有热门应用程序的几乎相同的克隆。
- 运行应用程序一小段时间以确定它们的功能。
- 安全研究人员在 Google 的应用程序扫描程序上获得了(非 root)shell。
- 事后合理预期:应用程序扫描程序只运行应用程序。
- Android 的应用市场(Google Play)允许 Google 远程停用应用程序。
移动电话应用程序中的安全性的另一种模型:iOS/iPhone。
- 安全机制:所有应用程序运行两个可能的 UID。
- 苹果应用程序一个 UID,其他所有应用程序另一个 UID。
- 从历史上看是有道理的:一次只有一个应用程序处于活动状态。
- 随着多任务应用程序的切换,未更改 UID 模型。
- 反而,使用苹果的沙盒隔离应用程序(“Seatbelt”?)。
- 最初苹果应用程序之间没有隔离(现在不清楚?)。
- 因此,浏览器中的漏洞利用使所有苹果应用程序“暴露”。
- 在使用时提示权限。
- 用户可以运行应用程序而不授予权限(不像安卓)。
- 在这个模型中,“普通”权限并不是很有意义。
- 苹果在其应用商店中批准应用程序,部分基于安全评估。
- “基于声誉”的系统:难以利用许多手机并避免被检测。