1 of 65

OTP 已死 U2F 永存�JavaScript U2F 兩步驟驗證實戰!

jong.sh/jsdc2016

js@jong.sh

2 of 65

About Me

  • 臺灣大學快速密碼學實驗室
  • 密碼學、程式語言、資訊安全、軟體工程

3 of 65

本日講題目標

  • 傳統密碼、SMS OTP、TOTP 為什麼不理想?
  • 認識 U2F 兩步驟身份認證
  • 實作 U2F 核心模組、虛擬硬體,心得分享

4 of 65

線上使用者身份認證

5 of 65

6 of 65

  • HTTPS (TLS) 幫我們解決了一個方向的問題
  • 下一個問題:如何證明使用者的身份?

7 of 65

傳統密碼身份認證

  • 簡單、易懂

8 of 65

9 of 65

傳統密碼身份認證

  • 簡單、易懂

  • 明文密碼出現於許多地方 => 許多可能的攻擊面
  • 使用者不知道服務方是否妥善處理密碼
  • 亂度低的弱密碼、重複使用的密碼
  • 釣魚
  • 沒有統一標準

10 of 65

傳統密碼身份認證 + 密碼管理員

  • 沒有密碼難記的問題,能輕易使用不重複的高亂度密碼
  • 「主要密碼」、「密碼資料庫」的安全性很關鍵

  • 沒有統一標準,許多工作難以自動化,盡是 dirty hack
  • 仍然是使用傳統密碼,許多缺點無法彌補

11 of 65

兩步驟驗證 (2FA)

  • 必須同時提供兩個合法 credentials 才能成功登入
  • 例子:密碼 + OTP

12 of 65

13 of 65

簡訊 OTP

  • 簡單、易懂
  • 不像密碼,OTP 會自動過期

  • 服務提供者需要額外支出
  • 完全依賴電信商網路的安全性
  • 收訊不佳時使用者體驗差
  • 釣魚
  • NIST 不建議使用簡訊 OTP

14 of 65

15 of 65

TOTP (每 30 秒更新一次)

  • 只要金鑰保存妥當,能提供很高的安全性

  • 手動操作步驟多,使用者體驗差
  • 純軟體解決方案,金鑰保存可能有問題
  • 釣魚

16 of 65

有大量使用者的線上服務

  • 在檯面上,最常被看到的資安事件主要可以分成:
    1. 想要竊取使用者個資
      • 弱身份認證實踐,搭配社交工程、各種釣魚,目標在於使用者
    2. 想要打擊服務方
      • 直接進行攻擊伺服器架構、網路,目標在於打擊服務本身
    3. 想要竊取服務方情資
      • 不留痕跡入侵、長期潛伏蒐集情報

  • 第一點數量不斷增加,造成損失之大愈來愈不可忽視
  • 從長遠的角度去看,雖難以察覺,但 APT 之威脅更大

17 of 65

資安,必須考慮的面向非常多

  • 系統愈大,攻擊面愈多
  • 敵人只需一個突破口,防禦方必須考慮全面
  • 和人(員工、合作夥伴、客戶)扯上關係的議題更難
  • 最重要的:風險評估管理、資安事件應變處理

  • 「使用者身份認證」只是一個小元件,但也無法忽視

18 of 65

線上使用者身份認證�如何改善?

19 of 65

U2F 是個兩步驟驗證的解決方案

  • 公鑰數位簽章
  • 硬體和軟體應用平台整合
  • 易用性與安全性

  • Password + U2F 能夠取代 Password + OTP

20 of 65

21 of 65

基於公鑰數位簽章的 U2F

  • 橢圓曲線數位簽章,密鑰不離開本地硬體
  • 定義元件之間標準介面,減少使用者操作
  • 自動編碼 HTTPS 網址到簽章訊息內,防止釣魚
  • 自動為不同網站生成不同的 key pair,保護使用者隱私
  • 使用 counter 偵測裝置、密鑰被複製、偷竊的情況
  • 不需第三方介入
  • 由業界發起、制定的標準,各大應用平台都將實作之

  • 支援度逐步增加,雖然目前還不夠廣泛

22 of 65

23 of 65

24 of 65

U2F 並沒有解決...

  • 如果 TLS 連線被攻破...
  • 如果使用者的瀏覽器已經被入侵...
  • 如果使用者的作業系統已經被入侵...

  • 以上是關聯、但無法只被身份認證技術解決的安全議題

25 of 65

U2F 標準文件

https://fidoalliance.org/specs/fido-u2f-v1.0-ps-20141009/

  • 建議閱讀順序:
    1. Overview
    2. FIDO U2F JavaScript API
    3. FIDO U2F Raw Message Formats
    4. 其他

26 of 65

FIDO 聯盟 (2012-)

  • FIDO = Fast IDentity Online
  • 跨平台的公開標準,處理線上身份認證

  • 目前已經發佈的標準文件:
    • U2F = Universal 2nd Factor
    • UAF = Universal Authentication Framework
    • W3C FIDO 2.0 Draft

27 of 65

U2F 框架下的三種角色

  • U2F Relying Party (網站)
  • U2F Client (瀏覽器)
  • U2F Authenticator (使用者端特殊的安全裝置)
    • 又稱 U2F Token / U2F Device / U2F Security Key

U2F�Client

U2F�Authenticator

U2F�Relying Party

req/res

req/res

28 of 65

U2F Client

U2F Authenticator

U2F RP (Client-Side)

U2F RP (Server-Side)

29 of 65

Google Chrome

YubiKey

a web page of Dropbox

Dropbox backend server

30 of 65

U2F Client

U2F Authenticator

U2F RP (Client-Side)

U2F RP (Server-Side)

兩種 challenge-response 訊息:

  1. Registration
    1. 檢查裝置是否已註冊過
    2. 請裝置產生新的 key pair
    3. 將 public key 和其他訊息回傳

  • Authentication
    • 請裝置對一個挑戰訊息簽章
    • 將數位簽章和 auth counter 等其他訊息回傳

U2F Client�JavaScript API

31 of 65

U2F Client

U2F RP (Client-Side)

U2F Authenticator

U2F RP (Server-Side)

四種 APDU 指令:

  • GetVersion
  • Register
  • CheckKeyHandle
  • Authenticate

U2F Raw Message�Protocol

Framed over USBHID,�NFC, Bluetooth, or BLE

32 of 65

愈來愈多線上服務支援 U2F 兩步驟驗證了

33 of 65

如果您作為使用者重視某些帳戶的安全性

  • 登入線上服務請愛用密碼管理員
  • 登入 SSH 請愛用 public key 認證
  • 先規劃好備援方案:如果帳戶被盜了,有辦法解決嗎?
  • 定期 review 帳戶安全設定
  • 啟用 2FA
  • 2FA 可以考慮 U2F 目前已經有不少硬體產品

34 of 65

如果您是網站開發人員

  • 用 argon2/scrypt/bcrypt/pbkdf2 處理密碼
  • 如果你重視使用者帳戶安全,請提供 2FA 選項
  • SMS OTP 有總比沒有好,但即將被淘汰
  • TOTP 仍然是個低成本的好選擇
  • U2F 完全可以取代傳統的 OTP 並且提供更高安全性

35 of 65

如果 U2F token 弄丟了怎麼辦?

36 of 65

如果信用卡弄丟了怎麼辦?

37 of 65

如果密碼弄丟了怎麼辦?

38 of 65

把密碼弄丟了

兩種「弄丟」方式

  1. 你忘記密碼了
  2. 你覺得你的密碼可能已經被敵人知道(偷走、複製)

兩種應對方式

  1. 使用服務方提供的 Plan B (account recovery)
  2. 問:「為什麼你覺得你的密碼可能被偷走了?」
    1. 消除威脅之來源(否則沒有意義)
    2. 重設所有可能受影響的帳戶的密碼

39 of 65

把 U2F token 弄丟了

兩種「弄丟」方式

  • 你真的弄丟 token 了
  • 你覺得你的 token 的 private key 可能已經被敵人知道

兩種應對方式

  • 撤銷已經弄丟的 token (就像信用卡掛失)�若尚未登入就得採 Plan B 帳戶救援方案
  • 問:「為什麼你覺得 private key 可能被偷走了?」
    • 消除威脅之來源(例如使用安全的硬體實作,不要用不可靠的軟體)
    • 撤銷所有可能受影響的帳戶的 token

40 of 65

把 U2F token 弄丟了

  • 帳戶設定 U2F 時通常就要求準備好備援方案了
  • 一些人會選擇買多把 U2F tokens
    • 工作用 -> token 1 個人用 -> token 2
    • 留一把「緊急用」的 token 3 在保險櫃

41 of 65

許多線上服務,都有多種登入選擇

  1. 按下「忘記密碼」會採用的各種 Plan B (甚至客服電話)
  2. 密碼,甚至是多組密碼
  3. 多種 2FA 選項組合
  4. 有時候持有一個 access token 就能代表你的帳號
  5. 有時候持有一把 private key 就能代表你的帳號
  6. ...

  • 您的帳戶安全強度,取決於最弱的那一個選項

42 of 65

服務端軟體函式庫實作

43 of 65

concise/lightu2f-nodejs on GitHub

  • Pre-alpha 階段,作為學習研究用途
  • 約 ~1000 行程式
  • 全 JavaScript
  • 無外部依賴 (只使用 Node.js 內建模組)

44 of 65

U2F JavaScript API

  • google/u2f-ref-code on GitHub
  • 在前端載入 u2f-gae-demo/war/js/u2f-api.js 函式庫後會有 u2f 物件可以使用

45 of 65

Let's check out lightu2f

46 of 65

客戶端 U2F 虛擬硬體實作

47 of 65

Google Chrome 的 U2F Client 實作

  • 從 chromium 原始碼即可一窺究竟
  • https://chromium.googlesource.com/chromium/src
  • repo 很大,git clone 要花一些時間

48 of 65

Google Chrome 的 U2F Client

  • Chrome 裡內建的 U2F Client 邏輯,完全只用 JavaScript 實現,以一個 extension 形式內建於 Google Chrome
  • 這個 extension 名為 CryptoTokenExtension,而 ID 為 kmendfapggjehodndflmmgagdbamhnfd 對上提供這樣的 API:

  • 對下會去尋找可用的 U2F 裝置並且發出相對應的指令
  • 原始碼位於 /chrome/browser/resources/cryptotoken

var p = chrome.runtime.connect( ID );p.postMessage( <request> );�p.onMessage.addListener( <response_callback> );

49 of 65

google-chrome--show-component-extension-options

50 of 65

Google Chrome 如何和 U2F USB 裝置互動?

  • Chrome 裡內建的 U2F Client 和硬體互動,是透過他自己的 chrome.hid 與 chrome.usb 這兩個 JavaScript APIs

  • 不同作業系統有不同的原生 C++ 實作,例如看見 #include <linux/hidraw.h> 就明白是在 Linux 上想找 HID 裝置

51 of 65

一個 U2F USB 裝置如何接收來自瀏覽器的請求?

USB�packets

U2F HID�protocol�fragments

U2F raw�messages

U2F Transaction�Logic Processor

Secure Storage�for Secret Keys

52 of 65

如何使我的程式被辨識為一個 U2F 裝置?

  • 可以從 USB device driver 開始寫起...

53 of 65

Linux User-Space HID I/O Driver

  • 為 Linux 撰寫驅動程式,也不用從最底層 USB 開始做
  • Kernel 提供的 HID subsystem 讓我們能通過 /dev/uhid ABI 掛上自己撰寫的 user-space I/O driver for HID device!

54 of 65

讀寫 /dev/uhid 檔案

  • 以 read() 讀取 kernel → user-space 的 UHID 事件
    • 有應用想要打開 USB 連線、和我們通訊
    • 來自 host 的 HID report 請求內容

  • 以 write() 來發送 user-space → kernel 的 UHID 事件
    • 回覆來自 host 的 HID report 請求

55 of 65

在 Linux 上實現 USBHID 的 U2F 裝置

USB�packets

U2F HID�protocol�fragments

U2F raw�messages

U2F Transaction�Logic Processor

56 of 65

在 Linux 上實現 USBHID 的 U2F 裝置

U2F HID�protocol�fragments

U2F raw�messages

U2F Transaction�Logic Processor

read() bytes�from /dev/uhid

write() bytes�to /dev/uhid

57 of 65

在 Linux 上實現 USBHID 的 U2F 裝置

U2F HID�protocol�fragments

U2F raw�messages

U2F Transaction�Logic Processor

將密鑰保存在�指定的目錄下

read() bytes�from /dev/uhid

write() bytes�to /dev/uhid

58 of 65

concise/v2f-nodejs-linux on GitHub

  • Pre-alpha 階段,作為學習研究用途
  • 約 ~1000 行程式
  • 全 JavaScript
  • 無外部依賴 (只使用 Node.js 內建模組)
  • 目前僅支援 Linux,未來可以考慮 port 到其他平台

59 of 65

Let's see v2f in action

60 of 65

軟體解決方案安全性的侷限

  • 硬體提供較好的保護,金鑰從來就不需離開硬體,讓你�可以安全地將它「帶著走」
  • 軟體 virtual security key 需要將金鑰存放在檔案系統...�比較可能被攻擊者竊取

  • 解鎖 security key 時,要求使用者證明身份?�輸入 passphrase 以解鎖 keychain 內的密鑰?�(原本按一下按鈕、或輸入 yes 只是表示有人在而已)

61 of 65

總結

62 of 65

U2F 相較於 OTP 的優勢

  • 橢圓曲線公鑰數位簽章,不將秘密資訊交給別人
  • 標準規範各個元件需要支援的統一介面,較容易看見裝置開發商、平台開發者支援它
  • 每次註冊,就算同一個網站,也會自動生成不同的金鑰
  • 釣魚防護、中間人攻擊、簡易的金鑰複製(竊取)偵測

63 of 65

U2F 的幾點阻力

  • 使用者需要購買額外的硬體才行
    • e.g., YubiKey for $18
  • 使用者端的應用平台需要跟上標準,實作 U2F Client
    • Firefox 等其他瀏覽器尚未實作完畢
    • 尚未有作業系統原生支援,在 Android / iOS 平台需要額外的 app
  • 要重新教育使用者,培養新的習慣
  • 服務方需要部屬相關的程式碼、再次規劃資料庫
    • 和為了支援 OTP 所要做的更動量差不多

64 of 65

Questions ?

65 of 65

Thanks!

有更多和 U2F 相關的問題�歡迎來信至 js@jong.sh 和我討論