#書き込める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 |................|