LoginSignup
6
5

More than 3 years have passed since last update.

RESTでSESAMEのスイカ鍵をちょっとセキュアに

Last updated at Posted at 2019-05-13

SESAMEのAPIはすばらしいけど、、、

sesame miniを買ったのです。そしてSESAMEのBlog( https://ameblo.jp/candyhouse-inc/entry-12413908790.html )で紹介されていたラズパイ&SUICAの組合せで動かしていました。こいつは素晴らしい。玄関先にNFCリーダつけたラズパイをおいておけば、スマホのアプリを起動する手間すらいらない。iphoneをピットかざすだけでスイカを読み取って鍵があきます。

ただ、ある日気づいたんです。これ、いろいろ大切な情報が平文で入ってますよね、、、

ちょっとでもセキュアに

セキュリティはもう奥が深すぎて僕にはとても手が及ばないです。
せめて外においているラズパイに大切な情報が平文ってのだけどうにかしよう。ということで考えたのが以下。我が家には室内にもnature remo代わりのラズパイが可動してるのでそいつを利用します。
SUIKAGI ASIS-TOBE.png

RESTを使ってみたかった

今回RasberryPi間の情報のやりとりはRESTを使ってみました。SESAMEのAPIもRESTですし、僕自身仕事でRESTREST連呼してるので使ったかったんです。
参考にしたのはこちら
https://qiita.com/Morinikiz/items/c2af4ffa180856d1bf30

さてプログラミング

今回は2台のラズパイにそれぞれサーバのプログラムとクライアントのプログラムが必要になります。

ラズパイ宅内側

RESTとSESAME Blogをがっちゃんこです。
SUICAのIdmが一致しなかった場合は404、ここは適当アタックを避けるために遅延を入れたほうがいいのかも。

suikagi-takunai.py
# -*- coding: utf-8 -*-
from flask import Flask, jsonify, abort, make_response

import requests
import json


# login CANDY HOUSE account and get token
url = "https://api.candyhouse.co/v1/accounts/login"
head = {"Content-type": "application/json"}
payload = {"email":"a@bcd.com", "password":"abcd"}
response = requests.post(url, headers=head, data=json.dumps(payload))
token = response.json()["authorization"]

api = Flask(__name__)

@api.route('/getIdm/<string:userId>', methods=['GET'])
def get_idm(userId):

    if (userId == "0139XXXXXXXXXXXX") or (userId == "0139XXXXXXXXXXXX"):
        result = 'OK' + userId
        print result

        # unlock Sesame with token
        url_control = "https://api.candyhouse.co/v1/sesames/XXXXXXXXXXX/control"
        head_control = {"X-Authorization": token, "Content-type": "application/json"}
        payload_control = {"type":"unlock"}
        response_control = requests.post(url_control, headers=head_control, data=json.dumps(payload_control))

    else :
        abort(404)

    return make_response(jsonify(result))

@api.errorhandler(404)
def not_found(error):
    return make_response(jsonify({'error': 'Not found'}), 404)

if __name__ == '__main__':
    api.run(host='192.168.XXX.XXX', port=XXXX)

Linux系ならCURL使えば簡単にデバックできます。さすがREST。

curl -i http://192.168.XXX.XXX:XXXX/getIdm/YYYYYY

ラズパイ玄関外

先程のsesameBlogを元にラズパイをnfc認識するように設定してください
https://ameblo.jp/candyhouse-inc/entry-12413908790.html

そんでブログのページのコードを改造

suikagi-genkan.py
# -*- coding: utf-8 -*-
import requests
import binascii
import nfc
import time
from threading import Thread, Timer


# Suica待ち受けの1サイクル秒
TIME_cycle = 1.0
# Suica待ち受けの反応インターバル秒
TIME_interval = 0.2
# タッチされてから次の待ち受けを開始するまで無効化する秒
TIME_wait = 3

# NFC接続リクエストのための準備
# 212F(FeliCa)で設定
target_req_suica = nfc.clf.RemoteTarget("212F")
# 0003(Suica)
target_req_suica.sensf_req = bytearray.fromhex("0000030000")

print 'Waiting for SUICA...'
while True:
    # USBに接続されたNFCリーダに接続してインスタンス化
    clf = nfc.ContactlessFrontend('usb')
    # Suica待ち受け開始
    # clf.sense( [リモートターゲット], [検索回数], [検索の間隔] )
    target_res = clf.sense(target_req_suica, iterations=int(TIME_cycle//TIME_interval)+1 , interval=TIME_interval)

    if target_res != None:
        tag = nfc.tag.activate_tt3(clf, target_res)
        tag.sys = 3

        #IDmを取り出す
        idm = binascii.hexlify(tag.idm)

        #REST用のurlを生成
        url = "http://192.168.XXX.XXX:XXXX/getIdm/" + idm

        response = requests.get(url)
        print(response.text)

        print 'sleep ' + str(TIME_wait) + ' seconds'
        time.sleep(TIME_wait)
    #end if

    clf.close()

#end while

これから

文中でもちらと書きましたがこのままではidmはしから試されかねないので、idmが不正だったときに遅延させる仕組みとか、宅外のラズパイのステータスをLEDで表示したりとかさせたいです。

6
5
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
6
5