← すべてのツール
私たちのメモ

DevToysX-Device-Signature をオフライン検証する

signing secret をどのサイトにも貼らずに webhook 署名を確かめたいことがあります。DevToys は完全にオフラインで動くデスクトップのツール箱です——secret があなたのマシンから出ることはありません。

DevToys とは

DevToys はオフラインの「開発者のための十徳ナイフ」——本来なら一ダースの web ツールを開かせるような generator・converter・encoder をまとめたデスクトップアプリです。ここで使うのはその HMAC generator です。

signing secret にとってオフラインが大事な理由

UnifyPort の webhook 署名は、あなたの signing_secret を鍵にした HMAC です。web ベースのハッシュツールは便利ですが、その secret をページに貼らせます。DevToys はすべてローカルで計算し——どこにも送信しません——だから実際に使う secret のときはより安全な選択です。

DevToys で X-Device-Signature を検証する

UnifyPort は各配信をこう署名します:

X-Device-Signature = hex( HMAC-SHA256( secret, timestamp + "." + raw_body ) )

手で再現するには:

  1. 1. DevToys の HMAC generator を開き、ハッシュ関数を SHA256 にします。
  2. 2. signing secret を key 欄にプレーンな UTF-8 テキストとして貼り付けます。
  3. 3. 入力欄に <timestamp>.<raw_body> をそのまま貼ります——X-Device-Timestamp の値、ASCII のドット、そして raw body のバイト列:
  4. 4. 小文字 hex の出力を X-Device-Signature ヘッダと比べます。バイト単位で一致すれば、secret・timestamp・body がすべて揃っています。
1716800000.{"type":"message.received", … }

CyberChef かコードのほうが向くとき

  • CyberChef。 手順をつなげたいなら——body を base64 デコードしてから HMAC——1 つの recipe で、私たちの CyberChef の手順のほうが柔軟です。代わりに web ページへ貼る必要があります。
  • コードで。 繰り返すものはすべて、ハンドラ内で定数時間比較(timingSafeEqualhmac.compare_digesthmac.Equal)で検証し——決して == を使わないこと。

入力をどこから得るか

  • 入れる X-Device-Timestamp と raw body を得るには、webhook.site で配信を捕捉するか、smee.io で localhost に転送します。
  • ブラウザと共有できる recipe の便利さが欲しいですか? CyberChef の手順は同じアルゴリズムを実行します。

よくある質問

DevToys はどのプラットフォームで動きますか?
DevToys は Windows と macOS 向けのオフラインのデスクトップアプリです。signing secret を web フォームに貼りたくないときに使ってください。
なぜ DevToys は web ベースの HMAC ツールより安全なのですか?
完全にあなたのマシン上で動くので——入力した signing secret がサーバに送られることはありません。web ツールも client-side のことはありますが、デスクトップアプリならそれを信じる必要がありません。
計算した署名が X-Device-Signature と一致しません——何が問題?
よくある原因は 3 つ: signing secret が違う; ハッシュ前に body が変更された(JSON の再シリアライズ、空白除去、unicode 正規化); または timestamp を別のヘッダから読んだ——署名されるのは X-Device-Timestamp だけです。入力はリテラルのドットを挟んで <timestamp>.<raw_body> でなければなりません。

一致したら

同じ計算をハンドラへ移します——Node では crypto.createHmac、Python では hmac.new、Go では hmac.New——そして必ず定数時間関数で比較し、決して == を使わないこと。