スマートなダムウォッチで手首にTOTPトークン
(blog.singleton.io)- ありふれた Casio F-91W に Sensor Watch 交換ボードを入れ、Google と Github 用の 2FA TOTP コードを手首で確認するハッキングプロジェクト
- 既存の LCD、ボタン、ピエゾブザーはそのまま使い、ARM Cortex M0+ ボードだけを交換して、Bluetooth なしでもプログラム可能なウォッチフェイスとユーティリティアプリを実行する
- TOTP ウォッチフェイスは、QR コードから Base32 secret を抽出して 16 進バイトに変換し、
totp_face.cに入れてmovementを再ビルドする方式で動作する - あわせて作られた ratemeter ウォッチフェイスは、ALARM ボタン入力の間隔から毎分の速度を計算し、500/min 超は
Hi、1/min 未満はLoと表示する - 数か月のバッテリー寿命、既存の Casio ケース、Web ベースの wasm エミュレーター、修正可能なソースツリーが組み合わさり、F-91W を小さな手首用ハッキングプラットフォームに変えられる
Casio F-91W をプログラム可能な時計に変える
- Sensor Watch は Casio F-91W の既存クォーツムーブメントを置き換える ロジックボード
- F-91W は約 9000万台が販売されたことで知られるクラシックなクォーツ時計
- 新しいボードは既存部品をそのまま活用する
- 元の LCD ディスプレイ
- ボタン
- ピエゾブザー
- ボードは ARM Cortex M0+ ベースでプログラム可能
- Sensor Watch プロジェクトは、修正しやすいウォッチフェイスと、「complications」と呼ばれる小さなユーティリティアプリ群を提供する
- Bluetooth ラジオはないが、軽量な時計ケース、数か月のバッテリー寿命、自分で再ビルドできる構造が利点
1時間以内に作った機能
- ボード交換、2FA secret の設定、新しいウォッチフェイス作成まで約 1時間で完了
- Google と Github アカウントの OTP コードを手首で見られるように設定
- ボート漕ぎのストロークメーターやケイデンスメーターとして使える ratemeter ウォッチフェイスを新たに作成
- wasm ベースのエミュレーターがあり、コンピューター上でテストしやすく、個人ビルドを Web ページで直接実行して試せる
時計が提供するウォッチフェイスの流れ
- MODE ボタンを1回押すと 2FA トークン ウォッチフェイスに移動
- 2FA ウォッチフェイスで ALARM ボタンを押すと Google と Github のトークンを切り替える
- MODE ボタンをもう一度押すと、自作の ratemeter ウォッチフェイスに移動
- ratemeter では ALARM ボタンを定期的に押して、追跡中の対象の毎分速度を測定する
- このビルドには複数の標準ウォッチフェイスも含まれる
- ワールドクロック
- 日の出/日の入り計算機
- 月相表示
- 時計内蔵温度センサーのリアルタイム出力
- 24時間設定セレクター
- 時刻/日付設定モード
- Sensor Watch の
movementソースツリーには、pulsometer や orrery など他のウォッチフェイスもある - F-91W モジュールのアップグレード過程は John Graham-Cumming のブログ に記録されている
TOTP ウォッチフェイスの設定方法
- TOTP ウォッチフェイスは、現在時刻を一意性の源として使う 時間ベースのワンタイムパスワード を生成する
- Google や Github など複数の Web サイトへのログイン用 2 段階認証コードの生成に使える
- ALARM ボタンで設定済みの Web サイトと TOTP secret を切り替える
- 複数の Web サイトと secret をサポートするが、QR コードから secret を抽出してウォッチフェイスのソースコードに直接入れる必要がある
-
TOTP secret の追加手順
- コードを生成したい Web サイトから TOTP secret または QR コードを取得
- QR コードしかない場合は Stefan Sundin の Web サイト で secret を抽出できる
- 抽出結果は約32文字の英数字文字列で、Base32 エンコードされた TOTP secret
- secret をウォッチフェイスのコードに入れるには cryptii.com で Base32 を 16 進バイトに変換する必要がある
- TOTP secret は 大文字 で入力する必要がある
- 変換した 16 進バイトを TOTP ウォッチフェイスのソースコードに追加した後、
movementを再コンパイルする
-
totp_face.cの修正箇所- デモキーは削除でき、新しいキーをリスト末尾に追加するには
num_keysの値を 1 増やす keys[]配列の末尾に変換した 16 進バイトを追加する- 各バイトの前に
0xを付け、カンマで区切る - 既存の最後のバイトの後にもカンマを追加する必要がある
- 各バイトの前に
key_sizes[]配列の末尾には、追加した secret のサイズ、つまり今入れた hex バイト数 を追加するtimesteps[]配列の末尾には30項目を追加するlabels[][2]配列には表示ラベルを追加する- Google アカウントなら
{ 'g', 'o' }のようなラベルを使える
- Google アカウントなら
- デモキーは削除でき、新しいキーをリスト末尾に追加するには
ratemeter ウォッチフェイスの実装
- ratemeter ウォッチフェイスのコードは、メインプロジェクトに提出した pull request にある
- 実装の大部分は
ratemeter_face_loopという メインループ関数 内にある - この関数はボタン入力イベントと時計の tick イベントを処理する
- ウォッチフェイスは、間隔測定やアニメーション処理のために tick 周期を要求できる
movementはwatch_display_stringユーティリティ関数を提供する- Casio ディスプレイの制限された 7+ セグメント要素に英数字文字列を表示しようとする関数
- 任意の文字列を限られた画面にマッピングする問題と例外は ドキュメント にまとまっている
-
イベントごとの動作
EVENT_ACTIVATE- ウォッチフェイスが有効化されると、曜日表示領域に
RAを表示する
- ウォッチフェイスが有効化されると、曜日表示領域に
EVENT_MODE_BUTTON_UP- MODE ボタンを押すと次のウォッチフェイスに移動する
EVENT_LIGHT_BUTTON_DOWN- LIGHT ボタンを押すと LED 照明を点ける
EVENT_ALARM_BUTTON_DOWN- ALARM ボタンを押すと、今回の入力と前回の入力の間隔から 毎分速度 を計算する
- ウォッチフェイス状態に保存された tick カウンターを初期化する
RATEMETER_FACE_FREQUENCYで高速 tick 周期を要求する- この定数は 1/16 秒として定義されている
EVENT_TICK- 現在の速度をディスプレイに表示する
- 速度が 0 なら
raのみ表示する - 500/min より速ければ
ra Hiを表示する - 1/min より遅ければ
ra Loを表示する - それ以外では
ra %-3d pn形式で計算された速度を表示する - 最後に tick カウンターを増やす
購入情報と提携有無
- Sensor Watch は Oddly Specific Objects で入手できる
- Oddly Specific Objects との提携関係はない
1件のコメント
Hacker Newsのコメント
TOTPのシークレット値を任意のWebページに入力するのは気が進まない
Linuxでは
base32とodツールがすでに入っているかもしれず、Ubuntuではcoreutilsパッケージに含まれているそれ以外はプロジェクトとしては素晴らしいが、時計のデザインはちょっと不格好
https://gchq.github.io/CyberChef/
https://i.imgur.com/9MYqLvj.png
予期しないサーバー側の挙動がないか確認するために、XHRをすばやくオフにできる
デモでときどき変な**⌍記号**が見えるなら、これは「小さな7」
この時計では1桁目と3桁目の上下セグメント、つまりAセグメントとDセグメントが互いに結線されているため
https://joeycastillo.github.io/Sensor-Watch-Documentation/wi...
このディスプレイにどれほど多くの効率を詰め込んでいるのか、本当に驚く
通常の使用ではこれらの桁は0〜5だけ表示できればよく、1桁目は時計では0、1、2だけで足りるが、クロノメーターは59:59.99まで進む
これらの数字ではAセグメントとDセグメントを区別する必要がなく、理論上はクロノメーターが69:59.99まで行っても問題なかったはずだが、「1時間」で十分だと考えたようだ
8と9も上下セグメントを両方点灯するので、実際に問題になるのは7だけ
ついにHNに来たくなるコンテンツが出てきた
F-91WはおそらくA158W[1]と同じフォームファクターだと思うが、A158Wは価格の割に信じられないほど見た目のいい時計
どんな服にも合い、スタイリッシュなのに主張しすぎないので、もっと高い時計の代わりについ頻繁に着けてしまう
金属バンドが腕毛を引っ張るのではと心配なら、1年間で2回ほどしかなく、他の安価な金属バンドよりずっと少なかった
「スモーキー」な代替品が欲しいなら、A168WGG[2]はバンドにガンメタルグレーの色味があり、文字盤は黒く処理され、イルミネーターは文字だけを照らす
ただしA168はA158よりほんの少し大きいので、内部モジュールが同じように収まるかは分からないが、大きいならスペースも増えるのでおそらく可能だと思う
時計の話をさらにすると、作業用の黒いバンドの時計としてはGA-B2100-1AJF[3]を使っている
G-Shockにしてはかなりスタイリッシュで、スマートウォッチではないのに機能が多い
Bluetoothモデルは安いモデルより文字盤の色とトーンのコントラストがよく、服に合わせやすい
[1] https://www.amazon.com/Casio-A158WA-1-Water-Resistant-Digita... [2] https://www.amazon.com/dp/B08195YQLQ/ [3] https://www.amazon.com/dp/B09YG8F41Y/
Sensor Watchボードには純正Casioの593モジュールから提供される部品が必要
対応する時計の一覧はここで見られる
https://www.sensorwatch.net/docs/
同じ3ボタン配置でも別のムーブメントを使っているため動作しない時計: A168W、A700W、LA680W、B650W
一般に、3ボタンのデジタルCasioで、側面ライトではなくまともな「illuminator」バックライトがあるなら、593ではないので動作しない
このプロジェクトが本当に好きで、文字どおり毎日使っている
少し前にソースコード内でTOTPコードを定義する新しいインターフェースを実装したのだが、その作業のためこの記事の説明はもう正しくなくなった
今はこんな感じで動く
static totp_t credentials[] = {CREDENTIAL(2F, "JBSWY3DPEHPK3PXP", SHA1, 30),CREDENTIAL(AC, "JBSWY3DPEHPK3PXP", SHA1, 30),};https://github.com/joeycastillo/Sensor-Watch/blob/main/movem...
脈拍計を喘息の呼吸数測定器としても使えるようにユーザー較正も追加し、すでに命を救う助けになった
較正と温度補償機能もあり、時計の精度を年間約10秒程度まで高めてくれる
コミュニティも大きくなっており、多くの人がファームウェアをハックしに参加している
最近は誰かがこの時計向けのエンドレスランナーゲームを作った
https://github.com/joeycastillo/Sensor-Watch/pull/419
メンテナーたちも本当にいい人たち
時間をかける価値のある優れたオープンソースプロジェクトを探しているなら、これがぴったり
ドキュメントでは見つけられなかった
腕時計を再コンパイルして再フラッシュしなければならないなら、TOTP用途としてはかなり制限されそう
すばらしい
Casioの電卓時計向けにも、誰かがこういうものを作ってくれたらいいのにといつも思っていた
https://www.casio-intl.com/asia/en/calc/products/SL-760LC-BK...
SecurIDトークンでもこれが動くといいのに
本当に興味深い
Nixonで働いているのだが、こういうことをNixonのデジタル時計でも試してみたいし、筆者が似たような記事を書きたいなら無料の時計をいくつか用意できるかもしれない
なぜ自分のいちばん賢いスマートウォッチではこれを使えないのだろう
昔のCasioに戻りたくなってきた
https://github.com/ch1bo/garmin-otp-authenticator
これは本当にいいし、ダムなスマートウォッチで似たようなことをやってみようとも考えたが、運用上のセキュリティの観点で、TOTPがこんなに見えやすく簡単にアクセスできて大丈夫なのか気になる
時計をなくしたり盗まれたりしたらどうなるのか
どのサービスかすぐには分からないようにラベルを付けている
Pebbleには実質的にロックやセキュリティはないが、いずれにせよ第2認証要素にすぎない
ランダム生成パスワードをすでに知っていて、手首にTOTPがある可能性まで調べており、実際に自分の時計を盗めるなら、もう負けているし、その程度は利便性との交換として受け入れられると思う