RSAモジュールで公開鍵と秘密鍵

ActivityPubでPOSTするには電子署名が必要。
でも、こいつが簡単じゃない…それどころか、めっちゃわけわかめ。
今回のゴールは以下の3点。
秘密鍵公開鍵の生成
秘密鍵を使って対象文字列の署名、サインの生成
公開鍵を使ってサインの検証
その1)
秘密鍵と公開鍵の生成はopensslコマンドを使うのが手っ取り早い。
秘密鍵の生成
openssl genrsa -out private.key 2048
2048はbit長というか、言ってみれば強度という理解で大丈夫そう。2048ぐらいで生成するのが良いらしい。
できる秘密鍵は
-----BEGIN RSA PRIVATE KEY-----XXXXXXX----END RSA PRIVATE KEY-----
改行されて?整形されてるんだけど、このまま使うっぽい。
公開鍵の生成
openssl rsa -in private.key -pubout -out public.key
最初に作った秘密鍵を使って公開鍵を作る。
できる公開鍵は
-----BEGIN PUBLIC KEY-----XXXXXXX-----END PUBLIC KEY-----
改行されて?整形されてるっぽいんだけど、このまま使うっぽい。
とはいえ、jsonは改行不可なので、jsonに入れる場合は、改行を削除して一行にしたものを使う、のかな。
[07/26 12:05:16]追記。
改行は「\n」(バックスラッシュとn)に変換する…
その2)
秘密鍵ができたので、perlのCrypt::OpenSSL::RSAモジュールを使って署名。
lolipopにはないけど、ローカルにはcpanでインストールしたので使える。
Fediverse入門―非中央集権型SNSサーバを作ろう!(2)
ここに掲載されているsign.plをありがたくそのまま使わせていただくことした。
秘密鍵を使ってインスタンス生成。
my $key = Crypt::OpenSSL::RSA->new_private_key($pk);
↑$pkという秘密鍵の文字列を渡して作る。
インスタンス生成ってなんのこっちゃ?だけど、呪文の始まり、ことでOK。
さらに、sha256でハッシュ化しますよ、という呪文を追加。
$key->use_sha256_hash();
ここまでやったら、秘密鍵を使った署名ができる。
my $s = $key->sign(INPUT);
signという、そのままのモジュールにINPUT、署名対象の文字列を渡せばRSA署名の出来上がりとなる。
署名対象の文字列とは。
ここでは、HTTPSヘッダのSignatureに使うことを想定して
date:[半角空白]日付文字列
digest:[半角空白]sha-256=本文のハッシュ文字列
みたいなものを「改行」で繋いだもの。
その3)
で、このサインが本当に合ってるのか署名の検証をする。
検証に必要なのは「公開鍵」「サイン」「署名対象文字列」
今度は公開鍵を使ってインスタンスを生成する。
my $rsa = Crypt::OpenSSL::RSA->new_public_key($pubk);
↑$pubkという公開鍵文字列の文字列を渡してやる。
秘密鍵を使った署名と同じ呪文を公開鍵で作ったインタンスに対しても追加。
$rsa->use_sha256_hash();
ここまでやったら検証ができる
$rsa->verify(TARGET, SIGN)
対象文字列と署名が合っていたら1が返ってくる。
この対象に対してこのサインがされてますよ、の証明になる、という理解で大丈夫かな。
サインはおそらくほとんどの場合、base64でハッシュ化する・されているので、
MIME::Base64 モジュールを使って
encode_base64 decode_base64
が必要になってくる、はず。
lolipopだとRSAが使えない、perlのCrypt::OpenSSL::RSAモジュールが入っていないので、あまり頑張りどころでもないよな、と思いつつ、うまくいかないのはなんか、好かん。
そして、意図通りに署名できたので、肝心要一丁目一番地のActivityPubでFollow、AcceptへのPOSTをしてみたんだけど、401で弾かれる。なんでや。
最初のactor.jsonを作った時に、公開鍵はとりあえず、空でもテキトーな文字でもいいというので、ほんとテキトーな文字を入れたのが失敗だったかなあ。
今回作った公開鍵に入れ換えたけど、最初のデタラメ公開鍵が伝播して使われてるという可能性もあったりして。
[08/18 12:30:06]追記
単なるPEMのコピペミスが原因。
サインする、検証するやりかたは上記エントリ通りで間違いなかった。
ActivityPubにおそるおそる話しかけてみた
↑署名対象文字列、HTTPSignatureヘッダでも悶絶吐血の記録
全然関係ないけど、AIにサイバーパンクな最後の晩餐を描いてもらったら、矮人の宴という半村良的な絵面が出てきたぞ
» ローカル環境で電子書籍を作る、Macアプリ・Windows版ツール 「かんたんEPUB3作成easy_epub」
【電子書籍発売中】