Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance: 署名アルゴリズムの変更 / 鍵のサイズの変更 (Change of signature algorithm/cryptographic key size) #11129

Open
yuriha-chan opened this issue Jul 6, 2023 · 21 comments · Fixed by #13464
Labels
🔥high priority packages/backend Server side specific issue/PR 🐢Performance Efficiency related issue/PR

Comments

@yuriha-chan
Copy link
Contributor

Summary

配送ジョブにおける署名処理が重いので、暗号鍵の方式を変更して軽くしたい。

Details

Misskeyの鍵長がRSA4096bitと、MastodonのRSA2048bitとくらべセキュリティの高い設定になっているため、連合におけるノートの配送のボトルネックとなっている署名処理の計算コストが(7倍程度)大きい。

RSA2048bitで妥協するか、ECDSAやEdDSAなどの安全性を保ちつつ効率の良い署名アルゴリズムを使うことで、計算の負荷を減少させることができる。ECDSAやEdDSAを使うことにする場合、既存のサーバーは対応していないので、ユーザーの鍵はRSAとECDSAの保存しておいて、連合先サーバーとのネゴシエーションによって、渡す公開鍵を決める必要があると思われる。

参考までに各アルゴリズムのOpenSSLによる速度測定例を置いておきます。
(AMD EPYC 7B12: 1CPU当たりの性能)

  • RSA 2048bit
    • 署名:1517.4/s
    • 検証:52966.6/s
  • RSA 4096bit:
    • 署名: 220.6/s
    • 検証:14481.2/s
  • ECDSA 256bit (nistp256):
    • 署名: 45247.8/s
    • 検証:14689.2/s
  • EdDSA 253bit:
    • 署名: 23028.8/s
    • 検証:8359.5/s

Additional Info

署名用の暗号鍵はアカウント作成時に生成され、サーバー内に保管される。既存のユーザーの鍵を更新する場合、すべての連合先(一度だけメンションを送ったサーバーなども含む)に新しい鍵になったことを伝えるメッセージを、古い鍵で署名して伝える必要がある。実用的には、古い鍵を破棄せず、新しい鍵と両方持っておく必要があると思われる。

@yuriha-chan yuriha-chan added the ✨Feature This adds/improves/enhances a feature label Jul 6, 2023
@syuilo syuilo added 🐢Performance Efficiency related issue/PR packages/backend Server side specific issue/PR and removed ✨Feature This adds/improves/enhances a feature labels Jul 6, 2023
@syuilo
Copy link
Member

syuilo commented Jul 6, 2023

RSA 2048bitにするか

@yuriha-chan
Copy link
Contributor Author

とりあえずここを書き換えると新規ユーザーだけ2048bitにできますが、私の見た限りでは、鍵の長さが違うユーザーが混在していても特に問題なく動くみたいです。

@sorairolake
Copy link
Contributor

RSA-2048 (セキュリティ強度112 bit) は2030年末までによりセキュリティ強度の高い暗号技術や鍵長に移行することが推奨されています12。Mastodonなどもこの期限までにRSA-2048から移行する可能性は十分にあると思うので、RSA-2048に移行した場合は再度署名アルゴリズムや鍵長を変更することになる可能性があると思います。

なので、可能であるならばセキュリティ強度が128 bitのRSA-3072に移行するか、EdDSAなどのセキュリティ強度が128 bitの楕円曲線暗号にも対応するのが良いと思います。

Footnotes

  1. https://www.cryptrec.go.jp/list/cryptrec-ls-0003-2022r1.pdf

  2. https://www.ipa.go.jp/security/crypto/guideline/gmcbt80000005u7d-att/000090943.pdf

@sorairolake
Copy link
Contributor

ECDSA (NIST P-256) とEdDSAなら後者の方が高速かと思ったけどそうでもない?

@syuilo
Copy link
Member

syuilo commented Jul 21, 2023

とりあえず新規ユーザーだけでも2048bitにしとくか

syuilo added a commit that referenced this issue Jul 21, 2023
@u1-liquid
Copy link
Contributor

せっかく変えるならnistp256かed25519にしてほしい感ある
rsa2048は2025年12月31日で5年有効期間の証明書の最終発行日となってるので、2023年にこれにするのは流石におかしいかも

@syuilo
Copy link
Member

syuilo commented Jul 21, 2023

ECDSAやEdDSAを使うことにする場合、既存のサーバーは対応していないので、ユーザーの鍵はRSAとECDSAの保存しておいて、連合先サーバーとのネゴシエーションによって、渡す公開鍵を決める必要があると思われる。

が大変そう

@sorairolake
Copy link
Contributor

セキュリティ強度が128bitの暗号でも2050年末には置き換える必要がありますが、25年以上先のことなので今から移行するなら全く問題ないと思います。なので、RSAのままにするにしても、2030年末には置き換えることになるRSA-2048にするのではなく、RSA-3072にする方が良いと思いますし、少なくともRSA-4096よりはパフォーマンスが向上するはずです。

@u1-liquid
Copy link
Contributor

u1-liquid commented Jul 21, 2023

正しい https://datatracker.ietf.org/doc/draft-ietf-httpbis-message-signatures の実装が先かも
4.3. Multiple Signaturesで複数個の署名の提供ができるので、それで対応できる

ちなみにマストドンはrsa-256とhs2019だけをサポートしてる
https://github.com/mastodon/mastodon/blob/1e3b19230a48174acf524cf1a9f5a498e220ea7d/app/controllers/concerns/signature_verification.rb#L83
hs2019はdraft-ietf-httpbis-message-signaturesの03版以降draft-ietf-httpbis-message-signaturesからは消えているが、既に複数のソフトウェアが実装しているもので、
中身のアルゴリズムの名前を出さないことで安全性を高めようとしてたものらしい。実際の中身はなんでも良かったみたい

slofp pushed a commit to Secineralyr/misskey.dream that referenced this issue Jul 21, 2023
@nvsofts
Copy link

nvsofts commented Aug 1, 2023

既にリプライがありますが、
RSA-3072にするのがCRYPTREC「暗号強度要件(アルゴリズム及び鍵長選択)に関する設定基準」を考慮した上での、ある程度長期的に安全な方法だと考えます。

@tamaina
Copy link
Contributor

tamaina commented Jan 3, 2024

up (ioの配送が大変)

@tamaina
Copy link
Contributor

tamaina commented Feb 25, 2024

正しい https://datatracker.ietf.org/doc/draft-ietf-httpbis-message-signatures の実装が先かも

https://datatracker.ietf.org/doc/rfc9421/ になった

HTTPシグネチャで複数の方式で署名できるのはいいとして、"https://www.w3.org/ns/activitystreams" / "https://w3id.org/security/v1" においてユーザーの公開鍵を複数(種類)含めることはできないような…(そういう運用は想定されてないか)

@tamaina
Copy link
Contributor

tamaina commented Feb 25, 2024

「publicKeyには今まで通りのRSA4096公開鍵」「拡張したプロパティ(additionalPublicKeys?)に"publicKeyで署名された"楕円曲線等の公開鍵情報(の配列)」を含めるとかどうかしら

@tamaina

This comment was marked as off-topic.

@tamaina

This comment was marked as off-topic.

@tamaina
Copy link
Contributor

tamaina commented Feb 26, 2024

nodeinfoに解釈できる署名関数の種類が入っていてそれに基づいて署名を渡すのが望ましい?

@mei23
Copy link
Contributor

mei23 commented Feb 26, 2024

「publicKeyには今まで通りのRSA4096公開鍵」「拡張したプロパティ(additionalPublicKeys?)に"publicKeyで署名された"楕円曲線等の公開鍵情報(の配列)」を含めるとかどうかしら

名称はともかく多分そんな感じ

nodeinfoに解釈できる署名関数の種類が入っていてそれに基づいて署名を渡すのが望ましい?

「署名を渡す」がなんなのかわからないけど、Activityに署名する際に、相手が何を解釈出来るか (例えばnodeinfo等で) 提供する必要があるわね。

@tamaina
Copy link
Contributor

tamaina commented Feb 26, 2024

「署名を渡す」がなんなのか

= ヘッダのSignatureを作る

@mei23
Copy link
Contributor

mei23 commented Feb 26, 2024

実データで検証したのがあったのだわ

image

用語
Sign (Node crypto) → 署名
Verify (Joyent) → 検証 (現行のhttp-signatureモジュール経由のエンジン)
Verify (Node crypto) → 検証 (Node標準を使用しての実装)

考察
鍵アルゴリズム間の違いは概ね一般的に言われてる通り。
しかし、Node v16 (OpenSSL v1) に比べて v18 (OpenSSL v3) 以降は性能が大幅に劣化
しかし、JoyentのEdDSAの検証が異様に遅いのでNode標準で実装したほうがいいかも

どのアルゴリズムがいい?
RSA vs 楕円曲線 (ECDSA or EdDSA)
楕円曲線系強い、RSAのメリットの検証の速さはOpenSSL3がおうんこになったのでなくなった。

ECDSA vs EdDSA
EdDSA強い、ただ現状のJoyent実装の検証は異様に遅いのでNode標準で書き直した方がいい
ECDSAは利用可能曲線名のメタデータ連携しなければならなそうなので使いたくないかも (なお現状JoyentのサポートはNISTの3曲線のみ)
EdDSAは署名関数が固定なので、現状の署名関数SHA256 or SHA512決め打ちのような面倒がないかも

@mei23
Copy link
Contributor

mei23 commented Feb 27, 2024

上記検証コード
https://github.com/mei23/crytest

あと、現状のhttp-signatureモジュールのままed25519にすると、署名が10倍速くなって検証が40倍遅くなるので本末転倒感があるのだわ

@KisaragiEffective
Copy link
Collaborator

337b42b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔥high priority packages/backend Server side specific issue/PR 🐢Performance Efficiency related issue/PR
Projects
Development

Successfully merging a pull request may close this issue.

8 participants