2026年7月25日(土)掲載 2,955本日 25
HN6739

そのデータ構造の署名、実は危険かも?やりがちな「間違った方法」と落とし穴

Signing data structures the wrong way

malgorithms4か月前

議論

11
0malgorithmsスレ主674か月前

データ構造にデジタル署名を付与する際、単純にシリアライズして署名するだけでは不十分な場合があります。正規化(Canonicalization)の欠如や署名対象の範囲の誤りなど、一見正しそうに見えて実は脆弱な「間違った署名のやり方」について、そのリスクと注意点をまとめました。

1Retr0id4か月前

IDLにドメインセパレーターを入れるのは面白いけど、インバンド(常に存在する「型」フィールドのようなもの)にドメインセパレーターを入れることでも解決できるよ。

余談だけど、入力やデータモデルにもよるけど、正規化にはO(nlogn)の時間(フィールドをソートするコスト)がかかるね。

マルチセットハッシュを使って、明示的な正規化ステップなしで決定論的なハッシュを生成する別のアプローチをここに書いたから参考にしてみて: https://www.da.vidbuchanan.co.uk/blog/signing-json.html

2tantalor4か月前

protoで例が出ていたから、protoでの解決策を提案するよ。メッセージオプションを追加すればいい。

  extend google.protobuf.MessageOptions {
    optional uint64 domain_separator = 1234;
  }

  message TreeRoot {
    option (domain_separator) = 4567;
    ...
  }
3formerly_proven4か月前

この記事では、これらがまだ未解決の問題のように書かれているけど、ずっと前から解決済みのことだよ。

#1 BLOBに署名したら、署名を検証するまでその中身を触らない(いわゆる「暗号学的破滅原則」)
#2 署名は、送信はされないが鍵の導出に使われたり、MACに混ぜ込まれたりする「コンテキスト」に紐付けられる。これはHorton原則と呼ばれるもの。これにより、署名者と検証者はメッセージが意図するコンテキストについて「暗号学的に」合意しなければならなくなる。これを正しく実装しないと、すべての署名の検証が失敗するから、間違った実装は本質的にできないようになっている。

この記事は、まさに原則#2に違反する(マジックナンバーをプロトコルヘッダーに埋め込んで、誰かがそれをチェックしてくれるだろうと想定する)やり方を提案している。これは設計として不適切で、歴史的に見ても悪い結果を招くだけだよ。

原則#1と#2は、それぞれ数十年にわたって確立された暗号設計原則なんだ。

4Muromec4か月前

またしてもASN.1から学んだ教訓を学び直したわけか。この業界で働いているのが誇らしいよ!次は、データには常にバージョンを含めるべきだってことに気付くんだろうね。

5jeffrallen4か月前

当たり前のことをうまく説明しているね。ドメイン分離も、ドメイン識別子をIDLに入れることもどちらもいいけど、目新しい話じゃない。

暗号は難しい。正しく実装すること。ツールを活用すること。それだけだよ。

まったく、こんなことのために自分は年を取りすぎたよ。

6lukev4か月前

つまり、署名はそのメッセージが含まれるスコープにしか及ばない、って言っているだけでしょ?

「はい」という言葉に署名しても、何の質問に対する返答なのか分からなければ意味がない。署名には、それが意味を持つために必要なコンテキストが含まれていないと。

やり方はいくらでもあるけど、冗長なデータやストレージのオーバーヘッドについては慎重に考える必要があるね。概念自体はトリッキーじゃないよ。

7cogman104か月前

型をハッシュの一部として含めるのはどう?そうすれば記事の問題は避けられるし、データサイズも小さく済むでしょ。

8efitz4か月前

自分のデータ構造をネットワーク経由で送信するメッセージにする時は、いつも固定幅フィールドのmsgIdとmsgLenから始めるようにしているよ。

これならメッセージの識別問題を明示的に解決できるし、セキュリティやメモリ管理も簡単になる。ルーティングもこんな感じに減らせるしね。

switch(msg.msgId):

9volume_tech4か月前

名目型(nominal)か構造的部分型(structural)かという点が核心だね。コードを書いている時は型が具体的で、型が違えばコンパイラが怒ってくれるから直感的だけど、シリアライズした途端にその区別が失われるということに気付きにくいんだ。

10colek424か月前

DSSEはこれに最適だよ。スキーマがもっと必要ならin-totoを使えばいい。