LoginSignup
4
1

More than 1 year has passed since last update.

Felicaに書き込む練習

Posted at

書き込めるFelica

ICカードの規格であるFelicaには、Suica,PASMOのような交通系カードやnanacoやWAONのような流通系カードなどいろいろあります。それぞれのカードでフォーマットが異なりますが、ほとんどのカードは鍵付きで書き込む仕様になっており、nfcpyなどで暗号なしで書き込むAPIであるwrite_without_encryptionがあるのですが試してみることができせん。一般人の入手できるカードの中でも暗号なしで書き込めるカードがPASMOです。PASMOにはsuicaと同じ0x0003番のプライベート領域に加えて、Suicaにはないシステムシステムコード0xFE00番の共通領域があります。その中に、サービスコード0x39C9があり、6ブロックですが write w/o key 属性を持っています。

  System FE00 (Common Area)
  Area 0000--FFFE
    Area 3940--39FF
      Area 3941--39FF
        Random Service 229: write with key & read w/o key (0x3948 0x394B)
         0000: f9 49 db c2 08 00 00 f1 01 00 00 00 00 00 00 00 |.I..............|
        Random Service 230: write with key & read w/o key (0x3988 0x398B)
         0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
         *     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
         000F: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
        Random Service 231: write w/o key (0x39C9)
         0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
         *     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
         0005: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|

上記ダンプを出力するnfcpyを使ったコードはいろいろなところで見かけますが、20行足らずで誰が書いても同じになるでしょうから、出典を記さず貼り付けておきます。

import nfc 

def on_connect(tag):
  print(tag)
  # タグのIDなどを出力する
  if isinstance(tag, nfc.tag.tt3.Type3Tag):
    try:
      # 内容を16進数で出力する
     print('  ' + '\n  '.join(tag.dump()))
    except Exception as e:
     print("error: %s" % e)
  else:
    print( "error: tag isn't Type3Tag")

def main():
  with nfc.ContactlessFrontend('usb') as clf:
    clf.connect(rdwr={'on-connect': on_connect})

if __name__ == '__main__':
  main()

PASMOに書き込んでみる

0x39C9の2ブロック目に何らかのデータを書き込んでみます。

import nfc 
import binascii
import time
import logging

syscode=0xFE00
svccode=0x39C9
logging.basicConfig()
#logging.getLogger('nfc').setLevel(logging.DEBUG-1)

def on_connect(tag):
  print ("on connect")
  print (str(tag))
  if isinstance(tag,nfc.tag.tt3.Type3Tag):
    tag.idm,tag.pmm=tag.polling(system_code=syscode)
    tag.sys=syscode
    try:
      sc=nfc.tag.tt3.ServiceCode(svccode>>6,svccode&0x3F)
      bc=nfc.tag.tt3.BlockCode(2)
      data=tag.write_without_encryption([sc],[bc],bytearray(b"(c) Hiroaki Hata"))
      print("wrote")
    except Exception as e:
      print("exception:%s" % e)
  else:
    print("not Type3Tag")
  return True 

def main():
  print('start')
  with nfc.ContactlessFrontend('usb') as clf:
    clf.connect(rdwr={'on-connect':on_connect})

if __name__=='__main__':
  main()

write_without_encryptionの第3パラメータに16バイト分のデータアレイを指定します。0クリアしたければbytearray(16)で置き換えます。データシーケンスが見たければ、logging.getLogger('nfc').setLevel(logging.DEBUG-1)のコメントを外してください。

これを一回動作させたあとで、もう一度DUMPしてみます。

System FE00 (Common Area)
  Area 0000--FFFE
    Area 3940--39FF
      Area 3941--39FF
        Random Service 229: write with key & read w/o key (0x3948 0x394B)
         0000: f9 49 db c2 08 00 00 f1 01 00 00 00 00 00 00 00 |.I..............|
        Random Service 230: write with key & read w/o key (0x3988 0x398B)
         0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
         *     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
         000F: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
        Random Service 231: write w/o key (0x39C9)
         0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
         0002: 28 63 29 20 48 69 72 6f 61 6b 69 20 48 61 74 61 |(c) Hiroaki Hata|
         0003: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
         *     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
         0005: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1