Slide 1

Slide 1 text

!TBJUFO $PSF#MVFUPPUIͱ$SZQUP,JUΛ ར༻ͨ͠εϚʔτΩʔ։ൃ J04%$ -5

Slide 2

Slide 2 text

ࣗݾ঺հ w 5PNPBLJ4IJCBUB w (JU)VC 5XJUUFSTBJUFO w %F/"40.10.PCJMJUZ w ΧʔγΣΞαʔϏεʮ"OZDBʯͷ J04ΞϓϦ։ൃΛ͍ͯ͠·͢

Slide 3

Slide 3 text

Λങ͍·ͨ͠

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

͋ͱͰ௥Ճ 伴ͱυΞͷࣸਅ

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

෺ཧ͕ͳ͍ͱυΞ͕։͔ͳ͍

Slide 8

Slide 8 text

ͪΐͬͱෆศ

Slide 9

Slide 9 text

Ͱ։͚ΒΕΔΑ͏ʹ͠Α͏

Slide 10

Slide 10 text

Ͱಈ࡞͢ΔεϚʔτΩʔΛ ࡞Γ·ͨ͠ w ΞϓϦ͔ΒΫϧϚͷݤͷࢪৣɾղৣૢ࡞ w ۙ͘ʹΫϧϚΛݟ͚ͭͨ৔߹ʹ௨஌͢Δػೳ

Slide 11

Slide 11 text

ंࡌ୺຤ "SEVJOP ߏ੒ਤ ᶆݤૢ࡞ ᶃΞυόλΠζύέοτૹ৴ ᶄεΩϟϯɾ઀ଓ ᶅݤૢ࡞ࢦࣔ ΞϓϦ ΫϧϚ

Slide 12

Slide 12 text

ंࡌ୺຤ "SEVJOP ߏ੒ਤ ᶆݤૢ࡞ ᶃΞυόλΠζύέοτૹ৴ ᶄεΩϟϯɾ઀ଓ ᶅݤૢ࡞ࢦࣔ ΞϓϦ ΫϧϚ

Slide 13

Slide 13 text

$PSF#MVFUPPUI w J04͔Βར༻ՄೳͳެࣜϑϨʔϜϫʔΫ w %FMFHBUFϕʔεͰ࣮૷͢Δඞཁ͕͋ΓɺॲཧͷྲྀΕ͕௥͍ͮΒ͍

Slide 14

Slide 14 text

3Y#MVFUPPUI,JU w HJUIVCDPN1PMJEFB3Y#MVFUPPUI,JU w 3Y4XJGUϕʔεͰ$PSF#MVFUPPUIΛѻ͑ΔϥΠϒϥϦ w #MVFUPPUIσόΠεΛεΩϟϯͯ͠઀ଓ͢Δ·ͰͷॲཧΛ਺ߦͰهड़Ͱ͖Δ

Slide 15

Slide 15 text

class CentralManager: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate { var manager: CBCentralManager? = nil func start() { manager = CBCentralManager(delegate: self, queue: nil) } // MARK: - CBCentralManagerDelegate func centralManagerDidUpdateState(_ central: CBCentralManager) { guard central.state == .poweredOn else { return } central.scanForPeripherals(withServices: [smartLockServiceUUID]) } func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { central.stopScan() central.connect(peripheral) } func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { peripheral.delegate = self peripheral.discoverServices([smartLockServiceUUID]) self.connectedPeripheral = peripheral } // MARK: - CBPeripheralDelegate func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { guard let service = peripheral.services?.first(where: { $0.uuid == smartLockServiceUUID }) else { return } peripheral.discoverCharacteristics([smartLockCharacteristicUUID], for: service) } func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { guard let characteristic = service.characteristics?.first(where: { $0.uuid == smartLockCharacteristicUUID }) else { return } peripheral.setNotifyValue(true, for: characteristic) } } Πϕϯτຖʹϝιου͕ผΕ͓ͯΓɺ ॲཧͷྲྀΕ͕௥͍ͮΒ͍

Slide 16

Slide 16 text

let manager = CentralManager() manager .observeState() .startWith(manager.state) .filter { $0 == .poweredOn } .flatMap { _ in manager.scanForPeripherals(withServices: [smartLockServiceUUID]) } .take(1) .flatMap { $0.peripheral.establishConnection() } .flatMap { $0.discoverServices([smartLockServiceUUID]) } .flatMap { Observable.from($0) } .flatMap { $0.discoverCharacteristics([smartLockCharacteristicUUID]) } ॲཧΛ࿈݁ͯ͠ॻ͘͜ͱ͕Ͱ͖ɺ ॲཧͷྲྀΕΛ௥͍΍͍͢

Slide 17

Slide 17 text

ηΩϡϦςΟରࡦ w ंࡌثͷଘࡏ͸؆୯ʹ୳͠ग़͢͜ͱ͕Ͱ͖Δɻ w ंࡌثʹ୭Ͱ΋઀ଓͰ͖ͯ͠·͏ͨΊɺૢ࡞ίϚϯυ͕෼͔ͬͯ͠·͑͹ ୭Ͱ΋ΫϧϚͷυΞΛૢ࡞Ͱ͖ͯ͠·͏ w ૢ࡞ίϚϯυ͸#-&4OJGGFSΛ࢖͑͹ղੳͰ͖Δ ࣄલʹར༻Ͱ͖ΔϢʔβΛݶఆ͠ɺ ͦͷϢʔβ͔Βͷૢ࡞ͷΈड͚෇͚ΔΑ͏ʹ͢Δ

Slide 18

Slide 18 text

ղৣγʔέϯε ंࡌ୺຤ʹ઀ଓ νϟϨϯδίʔυΛऔಘ νϟϨϯδίʔυ ʮૢ࡞ίϚϯυʴνϟϨϯδίʔυʯ ɹͷ4)"ϋογϡΛੜ੒͠ɺ ɹൿີݤ &$%4" Ͱॺ໊Λ࡞੒ ʮૢ࡞ίϚϯυʴνϟϨϯδίʔυʯ ɹͱʮॺ໊ʯΛૹ৴ νϟϨϯδίʔυ͕༗ޮ͔֬ೝ͠ɺ ࣄલʹొ࿥͞Εͨެ։ݤΛར༻ͯ͠ ॺ໊Λݕূ ղৣ׬ྃίʔυΛฦ͢ ໰୊ͳ͚Ε͹ ΞϯϩοΫ৴߸ Λૹ৴

Slide 19

Slide 19 text

ղৣγʔέϯε ंࡌ୺຤ʹ઀ଓ νϟϨϯδίʔυΛऔಘ νϟϨϯδίʔυ ʮૢ࡞ίϚϯυʴνϟϨϯδίʔυʯ ɹͷ4)"ϋογϡΛੜ੒͠ɺ ɹൿີݤ &$%4" Ͱॺ໊Λ࡞੒ ʮૢ࡞ίϚϯυʴνϟϨϯδίʔυʯ ɹͱʮॺ໊ʯΛૹ৴ νϟϨϯδίʔυ͕༗ޮ͔֬ೝ͠ɺ ࣄલʹొ࿥͞Εͨެ։ݤΛར༻ͯ͠ ॺ໊Λݕূ ղৣ׬ྃίʔυΛฦ͢ ໰୊ͳ͚Ε͹ ΞϯϩοΫ৴߸ Λૹ৴

Slide 20

Slide 20 text

$SZQUP,JU w J04͔Β௥Ճ͞Εͨϋογϡੜ੒ɺ҉߸Խɺॺ໊౳ͷ ॲཧΛఏڙ͢ΔެࣜϥΠϒϥϦ w ͦͷͨΊJ04Ҏ߱ରԠͰͳ͚Ε͹ར༻Ͱ͖ͳ͍ w ͜Ε·ͰͷެࣜϥΠϒϥϦͰ͋ͬͨ$PNNPO$SZQUP΍ 4FDVSJUZGSBNFXPSLͰ͸ϙΠϯλΛҙࣝ͢Δඞཁ͕͕͋ͬͨɺ $SZQUP,JU͸4XJGU࣮૷ͷͨΊɺΑΓॻ͖΍͘͢ͳ͍ͬͯΔ

Slide 21

Slide 21 text

4)"ϋογϡੜ੒ $PNNPO$SZQUP let payload = "\(operationCode)_\(challengeCode)" var digestData = Data(count: Int(CC_SHA256_DIGEST_LENGTH)) _ = digestData.withUnsafeMutableBytes { mutableBytes in CC_SHA256(payload, CC_LONG(payload.utf8.count), mutableBytes.bindMemory(to: UInt8.self).baseAddress) }

Slide 22

Slide 22 text

4)"ϋογϡੜ੒ $SZQUP,JU let payload = "\(operationCode)_\(challengeCode)" let digest = SHA256.hash(data: payload.data(using: .utf8)!) let digestData = Data(digest)

Slide 23

Slide 23 text

ॺ໊ 4FDVSJUZGSBNFXPSL var error: Unmanaged? var privateKey: SecKey? var publicKey: SecKey? let osStatus = SecKeyGeneratePair([kSecAttrApplicationTag: "co.saiten.smartkey", kSecAttrKeyType: kSecAttrKeyTypeEC, kSecAttrKeySizeInBits: 256] as CFDictionary, &publicKey, &privateKey) guard osStatus == noErr else { return } guard SecKeyIsAlgorithmSupported(privateKey!, .sign, .ecdsaSignatureDigestX962SHA256) else { return } let signature = SecKeyCreateSignature(privateKey, .ecdsaSignatureDigestX962SHA256, digestData as CFData, &error) as Data?

Slide 24

Slide 24 text

ॺ໊ $SZQUP,JU let privateKey = P256.Signing.PrivateKey() let signature = try? privateKey.signature(for: digest) let signatureData = signature?.rawRepresentation

Slide 25

Slide 25 text

·ͱΊ w Ͱಈ࡞͢ΔεϚʔτΩʔγεςϜΛ։ൃ͠·ͨ͠ w 3Y#MVFUPPUI,JU΍$SZQUP,JUΛར༻͢Δ͜ͱͰɺ #-&௨৴ॲཧ΍҉߸ԽॲཧΛγϯϓϧʹهड़͢Δ͜ͱ͕Ͱ͖ͨ w ΫϧϚͱ͍͏ΨδΣοτΛ͍͡Δͷ͸ͱͯ΋ָ͍͠ w ࣍͸λίϝʔλʔΛ௥Ճ͍ͨ͠

Slide 26

Slide 26 text

DeNA Tech ͷ Twitter ΞΧ΢ϯτͰ͸ɺ
 DeNA ͷΤϯδχΞϦϯάʹؔ͢Δ
 ొஃࢿྉ΍ϒϩάΛ঺հ͍ͯ͠·͢ʂ ͥͻ Twitter ΛϑΥϩʔͯ͠Έ͍ͯͩ͘͞ʂ