iPhoneでFeliCaを読み取ってみた

 iPhoneでFeliCaを読み取ってみた

iPhoneでFeliCaを読み取ってみた
#potatotips #64

作ったライブラリ
https://github.com/tattn/NFCReader

0620564f0125b8b3b7f4fe40c10b8b4e?s=128

Tatsuya Tanaka

August 27, 2019
Tweet

Transcript

  1. iPhoneͰFeliCaΛಡΈऔͬͯΈͨ ాதୡ໵ (@tattn) #potatotips #64

  2. ాத ୡ໵ / ͨͳͨͭ (@tattn) • Yahoo!৐׵Ҋ಺ • iOSΞϓϦΤϯδχΞ @tattn

    @tanakasan2525 @tattn Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.
  3. iOS13ͰFeliCaͷ ಡΈॻ͖͕Մೳʹʂ (CoreNFC)

  4. SuicaͷσʔλΛྫʹ
 ಡΈࠐΈํΛ঺հ͠·͢ (৐߱ཤྺ)

  5. FeliCaͷಡΈࠐΈखଓ͖ͷϑϩʔ IUUQTXXXTPOZDPKQ1SPEVDUTGFMJDBCVTJOFTTUFDITVQQPSUJOEFYIUNM begin() connect() requestService() readWithoutEncryption() λάͷϙʔϦϯά։࢝ λάʹίϚϯυΛૹΕΔΑ͏ʹ઀ଓ αʔϏεͷଘࡏ֬ೝ (σʔλͷ༗ແ)

    αʔϏε಺ͷσʔλಡΈࠐΈ NFCTagReaderSession NFCFeliCaTag IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPODPSFOGD
  6. FeliCaͷಡΈࠐΈʹඞཁͳઃఆ • Info.plistʹPrivacyઃఆ/System CodeΛ௥Ճ • Capabilitiesʹ
 Near Field Communication Tag

    ReadingΛ௥Ճ Suicaͷ৔߹͸0003
  7. Sessionͷ࡞੒ & ϙʔϦϯάͷ։࢝ let session = NFCTagReaderSession( pollingOption: NFCTagReaderSession.PollingOption.iso18092, delegate:

    self ) session.alertMessage = "iPhoneΛSuicaʹ͚͍ۙͮͯͩ͘͞" session.begin() FeliCaΛಡΈࠐΉ࣌͸ISO18092Λࢦఆ /** * @enum NFCPollingOption * * @constant NFCPollingISO14443 Support both Type A & B modulation. NFCTagTypeISO7816Compatible and NFCTagTypeMiFare tags will be discovered. * @constant NFCPollingISO15693 NFCTagTypeISO15693 tag will be discovered. * @constant NFCPollingISO18092 NFCTagTypeFeliCa tag will be discovered. */ public struct PollingOption : OptionSet { public init(rawValue: Int) public static var iso14443: NFCTagReaderSession.PollingOption { get } public static var iso15693: NFCTagReaderSession.PollingOption { get } public static var iso18092: NFCTagReaderSession.PollingOption { get } }
  8. Tag ͷಡΈࠐΈ४උ public func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag])

    { guard case .feliCa(let tag) = tags.first else { return } session.connect(to: tag) { error in guard error == nil else { return } // TagͷಡΈࠐΈ (࣍ϖʔδ) } } delegateͰݕग़ͨ͠λάΛड͚औͬͯ
 ઀ଓ͢Δ public enum NFCTag { case feliCa(NFCFeliCaTag) case iso7816(NFCISO7816Tag) case iso15693(NFCISO15693Tag) case miFare(NFCMiFareTag) }
  9. ϒϩοΫσʔλͷಡΈࠐΈ let serviceCodeList = [Data([0x0f, 0x09])] let blockList = (0..<UInt8(10)).map

    { Data([0x80, $0]) } feliCaTag.requestService(nodeCodeList: serviceCodeList) { nodes, error in guard error == nil, nodes.first == Data([0xff, 0xff]) else { return } feliCaTag.readWithoutEncryption( serviceCodeList: serviceCodeList, blockList: blockList) { status1, status2, dataList, error in guard error == nil, status1 == 0, status2 == 0 else { return } // dataͷಡΈࠐΈ (࣍ϖʔδ) } } Service code: αʔϏε(σʔλ)Λಛఆ͢Δίʔυ Block list: σʔλͷऔಘํ๏/ҐஔΛܾΊΔ
  10. Suicaͷσʔλͷσίʔυ for data in dataList { let year = data[4]

    >> 1 let month = UInt16(bytes: data[4...5]) >> 5 & 0b1111 let day = data[5] & 0b11111 print("ར༻೔: \(year)/\(month)/\(day)") // 19/8/27 let entrance = UInt16(bytes: data[6...7]) let exit = UInt16(bytes: data[8...9]) print("ೖ৔Ӻ: \(entrance), ग़৔Ӻ: \(exit)") let balance = UInt16(bytes: data[10...11].reversed()) print("࢒ߴ: ", balance) } IUUQTXXXXEJDPSHX3"*-αΠόωن֨ *$Χʔυ year͕2000೥Λج४ʹ͍ͯ͠Δͷ͕໘ന͍
  11. όΠτ഑ྻΛIntܕʹม׵͢Δ֦ு extension FixedWidthInteger { init(bytes: UInt8...) { self.init(bytes: bytes) }

    init<T: DataProtocol>(bytes: T) { let count = bytes.count - 1 self = bytes.enumerated().reduce(into: 0) { (result, item) in result += Self(item.element) << (8 * (count - item.offset)) } } } XCTAssertEqual(UInt16(bytes: 0x35, 0x0B), 13579) XCTAssertEqual(Int(bytes: 0x07, 0x5B, 0xCD, 0x15), 123456789)
  12. ಡΈࠐΈɺͪΐͬͱ໘౗…

  13. FeliCaΛಡΈࠐΉϥΠϒϥϦΛ࡞Γ·ͨ͠ https://github.com/tattn/NFCReader

  14. NFCReader - ࢖͍ํ let reader = Reader<Suica>() reader.read(didBecomeActive: { _

    in print("ಡΈࠐΈ։࢝") }, didDetect: { reader, result in switch result { case .success(let suica): let balance = suica.boardingHistories.first?.balance ?? 0 reader.setMessage(balance) case .failure(let error): reader.setMessage("ಡΈࠐΈʹࣦഊ͠·ͨ͠") } }) ௒؆୯
  15. NFCReader - ࢖͍ํ Reader<Suica>() Reader<Nanaco>() Reader<Waon>() Reader<Edy>() Reader<FeliCa>() Reader<CustomTag>() ৭ʑରԠͯ͠Έ·ͨ͠

    ←Suica ←nanaco ←WAON ←্هͷશͯΛೝࣝ ←ࣗ࡞ͷλά ←Edy Pasmo, Kitaca, ICOCA, TOICAɺ manacaɺPiTaPaɺnimocaɺ SUGOCAɺ͸΍͔͚Μɺଞ ( )
  16. ·ͱΊɾײ૝ • CoreNFCΛ࢖ͬͯFeliCa (Suica) ΛಡΈࠐΉํ๏ɺ
 ࡞ͬͨϥΠϒϥϦΛ঺հ • Suicaͷ࢒ߴྖҬ͸2bytes͔͠༻ҙ͞Εͯͳ͍ͷͰ
 ೖۚͰ͖Δ্ݶΛ؆୯ʹ͸૿΍ͤͳ͍ࣄ΋Θ͔ͬͨ •

    FeliCaͷ࢓༷͸Sony͕೔ຊޠͰ
 ஸೡʹॻ͍͍ͯΔͷͰͱͯ΋Θ͔Γ΍͔ͬͨ͢
  17. References • https://developer.apple.com/videos/play/wwdc2019/715 • https://developer.apple.com/documentation/corenfc • https://www.sony.co.jp/Products/felica/business/tech- support/index.html • https://www.wdic.org/w/RAIL/αΠόωن֨%20(ICΧʔυ)

    • http://www014.upp.so-net.ne.jp/SFCardFan/ • https://ja.osdn.net/projects/felicalib/wiki/FrontPage