OAuth: How And Why?
Upcoming SlideShare
Loading in...5
×
 

OAuth: How And Why?

on

  • 5,049 views

 

Statistics

Views

Total Views
5,049
Views on SlideShare
5,043
Embed Views
6

Actions

Likes
12
Downloads
106
Comments
0

1 Embed 6

http://www.linkedin.com 6

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

OAuth: How And Why? OAuth: How And Why? Presentation Transcript

  • OAuth: How and Why? LI Daobing (盛大创新院) lidaobing@gmail.com @lidaobing July 2010
  • 目录 为什么需要 OAuth? OAuth 原理 OAuth FAQ
  • Sina 微博: 通过邮箱联系人邀请好友? 要不要先改密码,再来输入? 还是干脆直接放弃? 新浪还可相信,小网站呢?
  • Facebook 做法 1. 我确实是从 Facebook 点击过来的 2. 确实是 Google 的网站 3. 申请的权限仅限我的联系人
  • 查看权限, 回收权限 在整个过程中: 1. 密码没有泄漏给 facebook 2. 同时可以随时回收权限
  • 更多情形 一个 twitter 客户端 一个手机上的 rememberthemilk 客户端 slideshare 想直接从你的 google docs 里导出 PPT 一个 Blog 客户端 ...
  • 需求再整理 前提 我有一些数据储存在服务方A 第三方客户端B想访问/修改我的数据 需求 我想授权B访问我的数据,同时不暴露我的用户名和密码 这种授权可以随时回收 即使信息被窃听, 攻击者也无法伪造请求 即使有恶意中间人, 攻击者也无法伪造请求
  • OAuth 能满足你的需求!
  • 目录 为什么需要 OAuth? OAuth 原理 OAuth FAQ
  • 标准历史 2007-10: OAuth 1.0 2009-06: OAuth 1.0a 主要解决一个安全漏洞 (后面有详细介绍) 2010-04: RFC 5849 名词变更, consumer->client, ... 时间戳不要求递增 小修改
  • OAuth 词汇表 三方 客户端: client, 原称 consumer 服务端: server, 原称 service provider 资源所有者: resource owner, 原称 user (本文仍使用" 用户") 三凭证 (凭证即两个随机字符串, 分别为 key 和 secret) 客户端凭证: client credentials, 原称 consumer key and secret, 客户端在服务端注册后获得 临时凭证: temporary credentials, 原称 request token and secret 令牌凭证: token credentials, 原称 access token and scret
  • 请求流程
  • 详细数据流 (1/5) 缩写 CK: 客户端凭证key CS: 客户端凭证secret TK, TS: 临时凭证 key 和 secret AK, AS: 令牌凭证 key 和 secret (A 代表 access token)
  • 详细数据流 (2/5) 0. 初始状态, 客户端持有 CK 和 CS 1. 用户发起授权操作: 用户点击位于客户端上的一个按钮, 发起授权 2. 客户端申请临时凭证: 客户端向服务端发送 CK 和申请的授权(rights), 并用 CS 签名 3. 服务端返回临时凭证, 服务端首先校验签名, 服务端生成一对 TK 和 TS, 把 {TK: [TS, CK, rights]} 放入 cache, 把 TK 和 TS 发送到客户端 4. 跳转至登录页面 客户端把 {TK: [TS, client_user]} 放入 cache, 使用 TK 和回调URL (oauth_callback) 构造出登录 URL, 发送一个 301 响应让用户跳转至登录 URL
  • 详细数据流 (3/5) 5. 用户访问登录URL, URL中包含 TK 和 oauth_callback (回调URL) 6. 完成授权 如果用户没有登录, 服务端首先引导用户登录, 获得 server_user. 服务端根据 URL 中的 TK 提取出 CK 和 rights, 展示客户端的详细信息以及申请的授权。 用户点击同意后, 服务端产生 AK, AS 以及一个 verify_code (一个随机字符 串), 更新 cache 为 {TK: [TS, CK, rights, AK, AS, verify_code, server_user]}, 根据URL中的 oauth_callback 和 verify_code 构造出新的回 调 URL。
  • 详细数据流 (4/5) 7. 用户访问回调URL, 该URL 中包含 TK 和 verify_code 8. 客户端申请令牌凭证 客户端通过 TK 拿到 TS 和 user_id, 首先判定此时的用户与申请TK时用户一 致, 然后向服务器发送 CK+TK+verify_code, 并用 CS+TS 签名 9. 服务端返回令牌凭证 服务端通过 TK 从 cache 取出 [TS, CK, rights, AK, AS, verify_code], 校验 CK 一致, verify_code 一致, 签名正确, 销毁 cache, 持久化 {AK: [AS, CK, user_id, rights]}, 返回 AK 和 AS
  • 详细数据流 (5/5) 10. 客户端发起 API 请求 根据 API 文档准备数据, 加上 CK, AK, 使用 CS+AS 签名 11. 服务端返回 API 结果 根据 AK 从数据库中调出 [AS, CK, user_id, rights], 校验 CK 及签名, 检验 访问的 API 是否在授权范围内, 使用 user_id 对应的数据支持 API, 返回结果 到客户端
  • 请求流程 (补上每步发送的数据)
  • 签名范例 GET /photos?file=vacation.jpg&size=original HTTP/1.1 #请求 Path Host: photos.example.net #请求 Host Authorization: OAuth realm="Photos", oauth_consumer_key="dpf43f3p2l4k3l03", #CK oauth_token="nnch734d00sl2jdk", #TK/AK oauth_signature_method="HMAC-SHA1", #签名方法 oauth_timestamp="137131202", #时间戳 oauth_nonce="chapoH", #nonce oauth_signature="MdpQcU8iPSUjWoN%2FUDMsK2sui9I%3D" #签名 1. 从客户端发送到服务端的每个请求都需要签名 2. 除了前面讲到的数据外, 需要额外加上 oauth_timestamp(时间戳) 以及 oauth_nonce, 用于防止重放攻 击 (后面有详解) 3. oauth_signature_method 用于指定签名方法, oauth_signature 为签名 签名细节参见 RFC 5849 3.4 节 , 简单来说就是把请求的内容拼接为字符串 (包括 GET/POST), 然后使用 对应的密钥签名
  • 需求回顾 我想授权B访问我的数据,同时不暴露我的用户名和密码 用户名和密码都是在 A 服务器上输入的, 从未暴露 这种授权可以随时回收 在 A 服务器上随时可以回收 如果信息被窃听,数据不会有危险 API 请求需要用 CK+AK 来签名, 数据窃听只能听到 AK, 所 以无法伪造请求 (PS, 尽管新的标准要求在返回 TS 和 AS 必须使用 HTTPS, 但仍有大量服务器使用 HTTP) 如果有恶意中间人,数据不会有危险 理由基本同上, 不过恶意中间人能够给客户端返回假数据,误 导客户端,但仍无法伪造出对服务端的合法请求
  • 更多的安全细节 1. 客户端需要保存好 TS 2. TS 在服务端是明码保存的, 所以如果服务端被入侵, TS 可 能会泄漏 3. 服务端用户登录页面必须是 HTTPS 4. 服务端展示客户端凭证密码的页面必须是 HTTPS 页面(很多 现有服务不满足) 5. 服务端返回临时凭证和令牌凭证时必须是 HTTPS 协议(原始 OAuth 协议为应该, RFC 改为必须) 6. 凭证的密钥应当足够长(大部分服务使用 128bit 密钥, douban 的是 64bit) 7. OAuth 不保证 API中涉及到的保密数据的安全。
  • 本地客户端的 前面介绍的是网站客户端的情况,本地客户端跟网站主要有如下 几点差异 没有回调 URL 的概念, 服务端直接在用户授权后显示对应的 verify_code, 本地客户端提供一个输入框让用户来输入 本地客户端需要一个保存CS(客户端凭证密钥)的方案,防止 被恶意用户获取到, 当然也可以不在本地保存,直接从网上 获取(注意这步保密)。 如果使用嵌入网页的方法来让用户登录, 用户无法判定浏览 器是安全的,会减弱对你的客户端的信任。
  • 目录 为什么需要 OAuth? OAuth 原理 OAuth FAQ
  • 为什么不用 HTTPS Q: 前面提到的很多手段都是为了应对窃听和恶意中间人, 全部 用 HTTPS 不就行了么? 一般情况下, 一个 IP+端口只能部署一套 HTTPS 密钥,也就 是说没法玩虚拟主机了(因为在 Host 发送前TLS连接就必须建立好 )。 SNI 扩展支持 HTTPS 虚拟主机,但客户端方面 IE6 不支持, WinXP 下 IE所有版本, Chrome, Safari 不支持. Dreamhost 之类的 Host 供应商不支持 HTTPS 虚拟主机。 HTTPS 对服务器端压力也更大 HTTPS 密钥很昂贵, 比较便宜的godaddy 每年 30 美金左 右, 贵的可达数千美金一年
  • 为什么使用 HMAC-SHA1 Q: HMAC-SHA1 需要计算两次 SHA1, 有必要么? A: 签名是为了防止窃听者和恶意中间人伪造请求, 而其他更简单的签名 方法都存在安全风险 1. 比如使用 sign = SHA1(key+data), 中间人截获了 data 和 sign, 由 于 SHA1 算法的特性,对于构造出 data' = data + padding, 可以 计算出对应的 sign' = SHA1(key+data'), 伪造成功。 2. 比如使用 sign = SHA1(data+key), 中间人截获了 data 和 sign, 如 果我们能找到 data' 满足 SHA1(data)==SHA1(data'), 那么伪造请 求 data', sign 也能通过服务端的验证 3. 对于 HMAC: sign = SHA1(f1(key)+SHA1(f2(key)+data)), 没有前 面所说的两种风险。 4. 第二步 SHA1 的参数很短(320bit), 所以对比单次 SHA1, 时间不是两 倍,而只是增加了一个很小的常数时间
  • 为什么需要 nonce 和 timestamp A: 防止重放攻击 (Replay attack) 一种重放攻击是把截获到的请求重发一次或多次, 对于 POST 这种非幂等的方法会造成服务器端的数据错误。加入 nonce 后, 首次之后的请求会被拒绝。这种攻击手法只需要窃听能 力。 另一种重放攻击是把请求拦截下来, 不发给服务器。然后等 待到合适的时间后再把请求发给服务器。也可以收集多个请 求,重新组合成合适的顺序后再发送。这种攻击手法需要中间 人能力。 由于 nonce 与 timestamp 是一起使用的,所以 timestamp 过期 后 nonce 也可以抛弃, nonce 储存容量不会无限制增长。
  • 1.0a 修复了什么Bug? A: 1.0 下存在如下的一种攻击手法
  • 1.0a 修复了什么Bug? A: 1.0 下存在如下的一种攻击手法 1. 存在两个用户: 攻击者和受害人, 存在一个客户端,这个客 户端会把用户在服务端的权限通过 OAuth 绑定到本地帐号。 2. 攻击者登录客户端, 在客户端触发 OAuth 请求, 跳转到服务 端后,不进行授权操作,保存此时的 URL。 3. 攻击者把保存好的 URL 发给受害人, 并诱导受害人完成授权 操作(注意: 此时绑定操作通常会失败, 因为因为临时凭证的 密钥部分应该只存在攻击者的 session 数据中)。 4. 攻击者访问 callback URL, 就可以绑定受害人的权限到攻击 者的帐号。
  • 1.0a 如何修复Bug? 服务器应该提醒用户, 登录链接是否来自指定的网站。 客户端应当确认,发起请求的用户和完成登录的是同一个用 户 (避免在受害者访问 callback 时就完成绑定了) 服务端会下发确认码, 攻击者无法构造出完整的 callback url, 攻击失败 申请临时凭证的协议也略有更改,用于识别 1.0a 客户端和 服务端
  • OAuth 不做什么? 只保护服务端,不保护客户端 OAuth 只保证用户在服务端的数据不被非法访问或修改, 但不保证客户端接收到正确的数据,恶意中间人可以修改 返回的数据,当然这个也可以用签名来解决。 不保护恶意浏览器/恶意操作系统攻击 用户必须自行确认自己的浏览器/操作系统是否安全。 OAuth 的安全建立在 HTTPS 之上, 攻击 HTTPS 的手段也会 影响到 OAuth 比如 DNS 污染加上伪造证书 比如 SSL 2.0 漏洞 不保护笨蛋, 用户需要教育 OAuth 授权时需要验证确实在真实的服务器上, 避免被恶意 客户端钓鱼
  • 国内现有 OAuth 服务器的问题 Douban 仍在使用 OAuth 1.0 客户端令牌展示页面没有加密 密钥只有 64bit Sohu 微博 每次认证时都要求用户输入密码, 容易造成用户麻痹, 更 容易被钓鱼网站袭击 ... PS. 仅代表当时(2010-07)的情况, 不代表现状
  • Thanks for your attention! Q&A?