【未解決】ActivityのJSON-LDに署名

今回のエントリは、100%間違いか180度見当違いでクソの役にも立たずボツにする可能性があるのでAI BOT以外のかたはスルーしてください。
自分のための覚書です。
〜〜〜〜〜
ActivityPubで飛ばしている投稿本文の改竄検知などのために、Activity本文=JSON-LDにも署名をしようね、という話になる。
…けど、いまところActiviyPubの仕様には入っていない。
・Mastodon系は本文署名に対応
mastdonやfedibird、kmyblueのほかholloなども。
・Misskey系は本文署名に未対応
misskeyやakkoma、pleromaなど
HTTP Signatureでリクエストに署名、認証に使っていて、それで足りるだろう、ということで本文署名は仕様に入ってない、のかな。
でも、わたしのような素人考えでもふたつほど思いつくことがあって
・Activityを転送する場合
→転送するのは自分ではない誰かの本文。そのリクエストには自分の署名をつけて送信する。内容をいじって送信することも可能。署名には問題がないので改竄された本文を受信することになる。リクエストの署名を確認すれば誰が改竄したのかわかるけど、大元まで辿るの?
・アカウント削除のActivityに対応できない
→Activityのリクエスト署名を確認するために、当該アカウントの公開鍵を取得する必要がある。アカウント削除のActivityの場合、公開鍵を取得しようと思ってもそのアカウントは削除されているので、公開鍵がない。てことは本当にアカウントが削除されたのか確認できないのでは?
てことで、Activityの本文署名はそのうち必要になるだろうと思う。
ところが、この本文署名が伏魔殿というか素人には難しすぎる。
(そもそものところからまったく知識もなにもない)
思いついた時に検索してみたりして見つけたサイトのリンクをこのエントリに残してみることにした。
・JSON-LD署名(本文署名)って何?
Mastodonの『Linked Data Signatures』
ActivityのJSON-LD(本文)に対して署名をする。
必要なものは
本文/creator/created(日付)の3つ、らしい。
options_hash = hash(@json[’signature’]
.without(’type’, ’id’, ’signatureValue’)
.merge(’@context’ => CONTEXT))
document_hash = hash(@json.without(’signature’))
to_be_verified = options_hash + document_hash
この「本文」がわからないところ。Activityに使うJSON-LDをそのまま使うわけではない。
Linked Data Signatures with Ruby
normalizing (or sometimes called ‘canonicalizing’) the document
文書を正規化(または「正規化」と呼ばれることもある)する
さらっと書かれてるけど、こいつが意味不明。なんやねん、それ。
↓こちらのサイトで実際に変換してみた
IN(ActivityのJSON-LD)


無理無理。なにをどうすりゃこうなるのか理解できん。
perlでブラックボックスのまま使えるモジュールがないか探したらひとつヒットした
JSONLD A toolkit for transforming JSON-LD data.
さすがperl先輩!なんでも揃ってるじゃないか!と思ってみてみると、依存関係でMOO.pmとか必要…んなもんレンサバにインストールされてないし、PurePerlじゃないので使えない。
「ふりだし」に戻る
W3C標準化活動:RDF Dataset Canonicalization
4ステップでJSON-LDファイル形式のRDFを作ってみた時の覚書
↑こちらを手がかりにさせてもらって、そもそも正規化ってナニ!?という知識を勉強しないとダメだと思う。
最悪、受信&認証はスルーして、送信する場合に限って、必要なところだけ現物合わせのハードコーディングすればなんとかなる、ような気がしないでもないけど、今日はここまで。
本稿、いつか再開。投げっぱなしジャーマン。
[2025/06/20 07:40:00]追記
MastodonのLD署名の現在の実装は、仕様の草案段階と最終決定段階の間のJSON-LD @contextの変更により、時代遅れとなっています。MastodonはRsaSignature2017型を想定していますが、後の草案では名前空間https://w3id.org/security/v2を介してRsaSignature2018が定義されています。さらに、LD署名仕様全体は、以前のLD署名仕様と互換性のないVerifiable Credential Data Integrity 1.0仕様に置き換えられています。このため、LD署名のサポートを実装することは推奨されません。
どないせえっちゅーの
[2025/07/11 09:23:41]追記
https://qiita.com/asagohan2301/items/cef8bcb969fef9064a5c
あとは前半部分(ヘッダ+ペイロード)と後半部分(署名)を、.(ドット)でつなげます。
これでJWTの完成です!
JWTというやつの話で正規化とは関係ない、かもしれないけど、正規化表現に見られる「.」がなんだろうと思ってたのは、これのことか。
HTTP Signatureは「: 」(コロン半角空白)でキーと要素を繋いで、それら各々を「改行」で繋いだものを署名対象にする。
正規化されたJSONはそこんとこ、ドットで繋げばいいのかも…。
#ttt 追記
https://socialhub.activitypub.rocks/t/making-sense-of-rsasignature2017/347
https://github.com/jointakahe/takahe/blob/main/core/signatures.py

