Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ChromeからMacBookのTouchIDでWebAuthenticationする

Ed0317cb78915cc841fd1b9461a48120?s=47 kg0r0
July 01, 2021
8

 ChromeからMacBookのTouchIDでWebAuthenticationする

#iddance Lesson 1. 技術書典とDigital Identity技術の資料です
※ slideshareからSpeaker Deckに移行しました
https://www.slideshare.net/KentoGoro/idance-vol1-148260910

Ed0317cb78915cc841fd1b9461a48120?s=128

kg0r0

July 01, 2021
Tweet

Transcript

  1. Chrome͔ΒMacBookͷTouch IDͰ WebAuthentication͢Δ Identity Dance School Lesson1 ٕज़ॻయͱDigital Identityٕज़ @kg0r0

  2. ࣗݾ঺հ • ߹࿏ ݈ਓ • ࣾձਓ3೥໨ • งғؾͰOAuth΍FIDOͯ͠Δ

  3. Ϙπཧ༝ • σϞ͕೿खͳͷʹॻ੶ͩͱө͑ͳ͍ • ΄ͱΜͲSELF Attestationͷઆ໌ͰChromeͱ ͔Touch ID͋Μ·Γؔ܎ͳ͍

  4. ಈ࡞؀ڥ • MacBook Pro (13-inch, 2016) • macOS Mojave version

    10.14.4 • Chrome version 74
  5. σϞ

  6. ҧ͍ • Yubico Security Key → packed FULL Attestation •

    Touch ID → packed SELF Attestation
  7. Registration Flow Ҿ༻ݩIUUQTXDHJUIVCJPXFCBVUIO

  8. Registration navigator.credentials.create({ publicKey: { rp: { id: "example.com”, name: "Acme"

    }, user: { id: new Uint8Array(16), name: "john.p.smith@example.com", displayName: "John P. Smith " }, pubKeyCredParams: [{ type: "public-key", alg: -7 }], attestation: "direct", timeout: 60000, // must be a cryptographically random number sent from a server challenge: new Uint8Array([ 0x8C, 0x0A, 0x26, 0xFF, 0x22, 0x91, 0xC1, 0xE9, ... ]).buffer } })
  9. Registration

  10. Registration ͪͳΈʹγʔΫϨοτϒϥ΢βͩͱཁٻ͞Εͳ͍

  11. Registration Flow Ҿ༻ݩIUUQTXDHJUIVCJPXFCBVUIO

  12. AuthenticatorAttestationResponse { "rawId": "imCIoe8U_N9M1rTGeCqJ96TAu5uqSPa7YUzd ... ", "id": ” imCIoe8U_N9M1rTGeCqJ96TAu5uqSPa7YUzdh7qq ...

    ", "response": { "clientDataJSON": ”eyJjaGFsbGVuZ2UiOiJJSFdtWjFPa1MydDZLaH ... ”, "attestationObject": ”o2NmbXRoZmlkby11MmZnYXR0U3RtdKJjc2 ... " }, "getClientExtensionResults": {}, "type": "public-key” }
  13. AuthenticatorAttestationResponse { "rawId": "imCIoe8U_N9M1rTGeCqJ96TAu5uqSPa7YUzd ... ", "id": ” imCIoe8U_N9M1rTGeCqJ96TAu5uqSPa7YUzdh7qq ...

    ", "response": { "clientDataJSON": ”eyJjaGFsbGVuZ2UiOiJJSFdtWjFPa1MydDZLaH ... ”, "attestationObject": ”o2NmbXRoZmlkby11MmZnYXR0U3RtdKJjc2 ... " }, "getClientExtensionResults": {}, "type": "public-key” }
  14. Attestation Object CBORΤϯίʔυ͞Εͨެ։伴ͳͲΛؚΉσʔλ Ҿ༻ݩIUUQTXDHJUIVCJPXFCBVUIO

  15. { fmt: 'packed', attStmt: { alg: -7, sig: <Buffer 30

    46 02 21 00 f3 c8 07 b7 2d ce 45 7d 45 94 30 44 89 2c 85 36 c8 e1 1e 20 64 a2 6b 4d cc 74 ab 86 16 cd 53 c3 02 21 00 c1 77 e6 45 96 c9 ff 55 12 1c ... 22 more bytes> }, authData: <Buffer 49 96 0d e5 88 0e 8c 68 74 34 17 0f 64 76 60 5b 8f e4 ae b9 a2 86 32 c7 99 5c f3 ba 83 1d 97 63 45 5c 7d 17 d1 ad ce 00 02 35 bc c6 0a 64 8b 0b 25 f1 ... 150 more bytes> } Attestation Object CBORΤϯίʔυ͞Εͨެ։伴ͳͲΛؚΉσʔλ .BD#PPL5PVDI*%
  16. Attestation Statement Attestationͷݕূʹඞཁͳ৘ใͳͲ Ҿ༻ݩIUUQTXDHJUIVCJPXFCBVUIO

  17. Attestation Statement Attestationͷݕূʹඞཁͳ৘ใͳͲ • alg : ॺ໊࡞੒ΞϧΰϦζϜ • sig :

    ॺ໊ • x5c : X.509ূ໌ॻνΣʔϯ
  18. { fmt: 'packed', attStmt: { alg: -7, sig: <Buffer 30

    46 02 21 00 be 80 1a 66 cb 2b 11 d3 ba c6 94 10 17 05 56 ee 72 e1 75 ff 0d ec c1 46 17 96 7d 11 10 5f 1d 5c 02 21 00 fe e4 f7 09 64 97 4d f5 bd 3d ... 22 more bytes>, x5c: [ <Buffer 30 82 02 be 30 82 01 a6 a0 03 02 01 02 02 04 74 86 fd c2 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 2e 31 2c 30 2a 06 03 55 04 03 13 23 59 75 62 ... 656 more bytes> ] }, authData: <Buffer 49 96 0d e5 88 0e 8c 68 74 34 17 0f 64 76 60 5b 8f e4 ae b9 a2 86 32 c7 99 5c f3 ba 83 1d 97 63 41 00 00 01 58 f8 a0 11 f3 8c 0a 4d 15 80 06 17 11 1f ... 146 more bytes> } Attestation Statement Attestationͷݕূʹඞཁͳ৘ใͳͲ :VCJDP4FDVSJUZ,FZ
  19. { fmt: 'packed', attStmt: { alg: -7, sig: <Buffer 30

    46 02 21 00 f3 c8 07 b7 2d ce 45 7d 45 94 30 44 89 2c 85 36 c8 e1 1e 20 64 a2 6b 4d cc 74 ab 86 16 cd 53 c3 02 21 00 c1 77 e6 45 96 c9 ff 55 12 1c ... 22 more bytes> }, authData: <Buffer 49 96 0d e5 88 0e 8c 68 74 34 17 0f 64 76 60 5b 8f e4 ae b9 a2 86 32 c7 99 5c f3 ba 83 1d 97 63 45 5c 7d 17 d1 ad ce 00 02 35 bc c6 0a 64 8b 0b 25 f1 ... 150 more bytes> } Attestation Statement Attestationͷݕূʹඞཁͳ৘ใͳͲ .BD#PPL5PVDI*%
  20. FULL Attestation Attestation Statementʹx5cΛؚΉ ݕূखॱʢུ֓ʣ 1. AuthenticatorDataͱClientDataHash͔ΒsignatureBaseΛੜ੒ 2. x5cͷূ໌ॻ͔Βެ։伴Λऔಘ 3.

    algͱެ։伴ͱsignatureBaseͰsigΛݕূ :VCJDP4FDVSJUZ,FZ
  21. SELF Attestation Attestation Statementʹx5cΛؚ·ͳ͍ ݕূखॱʢུ֓ʣ 1. AuthenticatorDataͱClientDataHash͔ΒsignatureBaseΛੜ੒ 2. AuthenticatorData͔Βެ։伴Λऔಘ 3.

    algͱެ։伴ͱsignatureBaseͰsigΛݕূ .BD#PPL5PVDI*%
  22. Verify Attestation

  23. ·ͱΊ • Touch IDΛೝূثͱͨ͠৔߹ͷAttestation Format͸ packed SELF Attestation • ূ໌ॻ͔Βऔಘͨ͠ެ։伴Ͱ͸ͳ͘Authenticator

    Data ͔Βऔಘͨ͠ެ։伴Ͱݕূ • ೝূ࣌͸ͦͷଞϑΥʔϚοτͱಉ͡ (transportsͷࢦఆ ͸஫ҙ)
  24. ͓·͚

  25. Authentication Flow

  26. Authentication navigator.credentials.get({ publicKey: { timeout: 60000, challenge: new Uint8Array([ 0x79,

    0x50, 0x68, 0x71, 0xDA, 0xEE, 0xEE, 0xB9, 0x94, 0xC3, 0xC2, ... ]).buffer, allowCredentials: [{ id: cred.rawId, type: "public-key" }] }, }) USBOTQPSUT ௨৴खஈ ͷࢦఆʹ஫ҙ
  27. Authentication

  28. Authentication Flow

  29. AuthenticatorAssertionResponse { "rawId": "imCIoe8U_N9M1rTGeCqJ96TAu5uqSPa7YUzd ... " , "id": "imCIoe8U_N9M1rTGeCqJ96TAu5uqSPa7YUzdh7qq ...

    ", "response": { "authenticatorData": "SZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2MBAAAALQ", "signature": "MEUCIQCFOqnsAFZLQmcPt2qSjnCb403SisGEASSjT3fOPuD5JgIgF ...", "userHandle": "", "clientDataJSON": "eyJjaGFsbGVuZ2UiOiJDUXF5aUlrQ00yWEtvaHVSdlNqTEFoN ...” }, "getClientExtensionResults": {}, "type": "public-key” }
  30. AuthenticatorAssertionResponse { "rawId": "imCIoe8U_N9M1rTGeCqJ96TAu5uqSPa7YUzd ... " , "id": "imCIoe8U_N9M1rTGeCqJ96TAu5uqSPa7YUzdh7qq ...

    ", "response": { "authenticatorData": "SZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2MBAAAALQ", "signature": "MEUCIQCFOqnsAFZLQmcPt2qSjnCb403SisGEASSjT3fOPuD5JgIgF ...", "userHandle": "", "clientDataJSON": "eyJjaGFsbGVuZ2UiOiJDUXF5aUlrQ00yWEtvaHVSdlNqTEFoN ...” }, "getClientExtensionResults": {}, "type": "public-key” }
  31. Generating an assertion signature

  32. Verify Assertion ݕূखॱʢུ֓ʣ 1. ొ࿥࣌ʹอ؅ͨ͠ެ։伴ΛऔΓग़͢ 2. AuthenticatorDataͱClientDataHash͔ΒsignatureBaseΛੜ੒ 3. algͱެ։伴ͱsignatureBaseͰsigΛݕূ

  33. Verify Assertion

  34. ͳ͔ͥॺ໊ͷݕূʹࣦഊ͢Δ

  35. ͳ͔ͥॺ໊ͷݕূʹࣦഊ͢Δ

  36. ೝূ࣌ͷAuthenticatorData͕ Yubikeyͷ࣌ͱൺ΂ͯ௕͍ͧ??

  37. AuthenticatorData Ҿ༻ݩIUUQTXDHJUIVCJPXFCBVUIO

  38. AuthenticatorData Ҿ༻ݩIUUQTXDHJUIVCJPXFCBVUIO

  39. ݕূʹࣦഊ͍ͯͨ͠ཧ༝ • Ұ౓AuthenticatorDataΛ෼ղ͔ͯ͠ΒSignatureBaseΛ࡞͍ͬͯͨ • ೝূ࣌ʹAttestedCredentialData͸ؚ·Εͳ͍ͱࢥ͍ͬͯͨ • ೝূ࣌ʹChrome͸AttestedCredentialDataΛฦ͖͍ͯͯͨ͠ • ݁Ռͱͯ͠SignatureBase͕ෆ଍ͨ͠

  40. It can be longer than 37 bytes if extensions are

    sent (in which case the extensions bit is set in the authenticatorData flags). You are correct though, that the authenticator should not send attestedCredentialData for a GetAssertion operation. Ҿ༻ݩIUUQTCVHTDISPNJVNPSHQDISPNJVNJTTVFTEFUBJM JE
  41. Should be in Chrome 75. If you assume that we

    hit our six week cadence then Chrome 75 would be ~mid June. Ҿ༻ݩIUUQTCVHTDISPNJVNPSHQDISPNJVNJTTVFTEFUBJM JE
  42. ࢀߟ • Web Authentication: An API for accessing Public Key

    Credentials https://www.w3.org/TR/webauthn/ • FIDO2 attestation formatͷ঺հ https://techblog.yahoo.co.jp/advent-calendar-2018/webauthn-attestation-packed/ • FIDO2ʹΑΔChromeͱMacBook Proͷtouch idΛར༻ͨ͠ύεϫʔυϨεϩάΠϯͷ࣮૷ https://qiita.com/ifsec_56/items/0cc5f1d73e7d2e3029ad • Issue 946993: Touch ID authenticator returns attestedCredentialData in GetAssertion response http://kent056-n.hatenablog.com/entry/2019/03/31/140910 • WebAuthn/FIDO2: Verifying Packed Attestation ɹhttps://medium.com/@herrjemand/verifying-fido2-packed-attestation-a067a9b2facd