ひまつぶし雑記帖

doncha.net制作・発行:KindleやiBooks、楽天kobo、BOOK☆WALKERで読む電子書籍

ActivityPubにおそるおそる話しかけてみた

2023/7/26 [12:37:55] (水) 天気

ActivityPubを通じてフォローしたり投稿したりするには避けて通れないRSAの署名、というかサインというか。
これ絡みが、もう本当に五里霧中で迷走するばかり。
いろいろ検索しまくってこれでイケるかも?ぐらいのところまで来たので、いったんメモ。

RSAモジュールで公開鍵と秘密鍵
↑鍵を作ってサインする方法は前回のこれで正解。

一番の問題は、サインを作る対象となる文字列をどうするの、というところ。これはなんでもいいんだけど、ActivityPubに通すので、そっちに合わせる必要がある。

結論からいうと必要な材料は以下。
・リクエストのメソッド(POSTとかGET)とリクエストするURI
・相手側のホスト名
・日付、
・本文のDigest
mastodonの仕様だと必須なのは、日付とdigestの2つなんだけど、実際にmastodonから飛んでくるリクエストのログを見ると、この4つが必ず入っている。
オマケでcontent-typeやacceptを入れることもある、らしい。

具体例をあげると

(request-target) POST /actor/inbox
host: example.com
date: Wed, 26 Jul 2023 02:00:32 GMT
digest: SHA-256=unkTWZOjiNdJT4SDuAU6tCy6A0QM0PZ2bs0353xOt+k=
content-type: application/activity+json


「キー 区切り 値」の並び
host「:」「半角空白」example.com
という形式で、キーはすべてアルファベットの小文字。
(request-target)だけはコロンは不要

これら、ひとつひとつを「改行」で繋げて並べた文字列を対象としてサインすることになる。

digestというのは

元データから、ハッシュ関数と呼ばれるあらかじめ定められた計算手順により求められた値です。 ダイジェスト値とも呼ばれます。 ハッシュ値を求めるハッシュ関数(※)には、元データが1ビットでも異なれば大きく異なるハッシュ値が生成される(同じハッシュ値になることが実用上ない)方式が選ばれます。


perlだと「MIME::Base64」のencode_base64という関数をそのまま利用。
encode_base64(本文,"")と、2番めの引数に空を渡さないとDigestに改行がついてくるので注意。
本文というのはfollowやcreateといったActivityPubで使うjson文字列。

対象文字列が決まったら、RSAで署名して、リクエストのヘッダに入れる。

'host' => 'example.com',
'date' => 'Wed, 26 Jul 2023 03:52:07 GMT',
'digest' => 'SHA-256=unkTWZOjiNdJT4SDuAU6tCy6A0QM0PZ2bs0353xOt+k=',
'content-type' => 'application/activity+json',
'signature' => 'keyId="https://tokoroten.doncha.net/t2aki#main-key",algorithm="rsa-sha256",headers="(request-target) host date digest content-type",signature="qCEXfTo~略~I9zfRqcUaTwjew=="',


↑これはperlのlwpを使ってヘッダに設定している部分。
Signatureの
keyIdは「actor.json」に入れた公開鍵のkeyId
algorithmは暗号化の方法「rsa-sha256」

↓適宜改行は入れたけど、こんなリクエストを飛ばす

HTTP_DATE :: Tue, 25 Jul 2023 23:55:38 GMT
HTTP_DIGEST :: SHA-256=giwfKVIT61lc9LpR7EsgEJBmHilheDpPwFnqdjMBjrA=
HTTP_HOST :: example.com
HTTP_SIGNATURE :: keyId="https://tokoroten.doncha.net/t2aki#main-key",
algorithm="rsa-sha256",
headers="(request-target) host date digest content-type",
signature="SE〜略〜JEVPj9


サインの検証は問題ないし、リクエストもこれで問題ない、と思ったんだけど、mastodonだと401で弾かれる。firefishだと202でどうやら受け付けてもらえるっぽい。

同じリクエストを送ってるのになんでこっちはダメでこっちがOKなのか理解できていないのが現状。


その他ハマったところ。

公開鍵って改行されてるけど、actor.jsonのpublicKeyPemに入れるのにどーすんの問題。
jsonは改行入りデータは扱えない。ただただ改行を削除して一行にすればいいんだろ、ぐらいに思ってたんだけど、検索して眺めてると「バックスラッシュ」「n」という2文字の文字列になってるっぽい。これ、改行なのか2文字の文字列のことなのかわけわからず、ほぼ1日弱経過。
perlのJSONでencode_jsonしてみりゃいいことに気づいてやってみたら、2文字の文字列に置換されていた…改行を「バックスラッシュ」「n」の2文字の文字列て、なんか不細工じゃね。

(request-target)ってなんやねん問題。
どのリクエストのヘッダもこれが先頭にあったんで、てっきり、これに続く要素を要求しますよ、という宣言みたいなもんだと思ってたら大きな間違い。こいつもキーのひとつだった。
HTTPメッセージに署名をするSignatureヘッダの標準化

Digestの生成を疑った問題。
リクエストが401で弾かれっぱなしだったんで、どこが問題だろうと。HOSTやDateは目で見てわかる文字列で、そこは大丈夫だったので、Digestが違ってるわけ?と。
perlのDigest::SHA qw(sha256) MIME::Base64 encode_base64(sha256($content),"")で作ったDigestの検証。
コマンドラインで
cat accept.json | head -c -1 | sha256sum | xxd -r -p | base64
などとやって差分のないことを確認。Digestも問題なかった、やっぱり1日弱経過。


実際、まだマストドンからは401で弾かれるので、何か間違えてるはず。
とはいえ、 himagine.club (firefish)から202が返ってきたを見てめっちゃ嬉しかったので、ここらでひと段落とするかなあ。これ以上やったらただでさえマダラハゲなのに禿頭一直線になりそうで怖い。

mastodonのSignatureのソースコード
"#{Request::REQUEST_TARGET}: #{request.method.downcase} #{request.path}"
ActivityPubに対するSignatureのPHPのソースコード
'(request-target) %s %s%s'

あれ?(request-target)の後ろにコロンがいるのかいらないのかよくわからないぞ。コロン一つでverifyの結果が違う…て、どっちでやっても401だったけどな。
[07/27 19:52:17] うまく開通したスクリプトではコロンをつけた文字列。

[07/26 16:29:44] 追記
をっと。202が返ってきても繋がったわけじゃなかった。まだどことも繋がらないってこと。どこが違うんだろ。401じゃないってことはヘッダやサインは問題ない、という理解でいいのかな。これは根が深い。お手上げ、かなあ。

[07/27 11:21:59] 追記
開通!というかActivityPubを通じてFediverse連合空間に入ってfollowもpostもできた!

401の原因。
actor.jsonに記載のpublicKeyPemの始まりのハイフンがコピペミスでひとつ足りなかった。5つ必要なのに4つしかなかった…だけだった。
我ながら雑で阿呆なミスに愕然し、驚愕するばかり。

とはいえ、この何日か、けっこう必死こいて調べまくったので、SignatureやHTTPヘッダについて改めて知ったこともあったので、結果オーライ。

副産物というかverifyするスクリプトやログを片っ端から取るスクリプトを作ったのも今後役に立つだろうと思うし。

image

»電子書籍制作代行についてはこちら

profile

profile

 
doncha.net
contact:
»運営者
@t2aki@tokoroten.doncha.net

ところてんx5

2024/4/28 10:53

とりあえず。確認終了…で、いいよなあ。あとは、ルビについての申し送りテキストを書くのと、前回のルビや空行の抜け漏れのお詫び文面。
平謝りするのも違うような気がするので、対策について書くだけにする。

2024/4/27 12:51

図書館で作業。案の定、目視確認は一回じゃ抜け漏れが出る。
一応、最初に確認、反映させた箇所で大丈夫だったけど、これは先が思いやられる。

2024/4/27 08:52

もろもろ、問題山積でやる気が出なくてマズい。久しぶりに図書館の個人席にノパソ持ち込んで作業してみる、か。

検索
<<2024/4>>
 123456
78910111213
14151617181920
21222324252627
282930

リンク

WINDOWS版サウンドノベル
おかえりください PC WINDOWS版サウンドノベル
『おかえりください』体験版