simon
1
軽微な問題と、おそらくより大きな問題があります。
ドキュメントに記載されていない必須の nonce パラメータがあります。
def require_params
%i[public_key nonce scopes client_id application_name].each { |p| params.require(p) }
end
さて、より厄介な問題です。Discourse は引数なしで public_encrypt メソッドを呼び出します。
これにより、padding 引数はデフォルトで PKCS1_PADDING になります。Ruby のドキュメントによると (class OpenSSL::PKey::RSA - Documentation for Ruby 3.2):
string を公開鍵で暗号化します。padding はデフォルトで PKCS1_PADDING になりますが、これは安全ではないことが知られていますが、後方互換性のために保持されています。
残念ながら、Node v20.14.0 (現在の LTS) では、crypto.privateDecrypt を RSA_PKCS1_PADDING で呼び出そうとするとエラーが返されます。
function decryptData(data: string, privateKey: string) {
const buffer = Buffer.from(data, "base64");
const decrypted = crypto.privateDecrypt(
{
key: privateKey,
padding: crypto.constants.RSA_PKCS1_PADDING,
},
buffer
);
return decrypted.toString("utf8");
}
TypeError: RSA_PKCS1_PADDING はプライベート復号ではサポートされなくなりました。これは --security-revert=CVE-2023-46809 で元に戻すことができます。
Node アプリの可能な修正は、安全でないフラグで Node を実行することです。
node --security-revert=CVE-2023-46809
Discourse 側での修正は簡単ですが、多くの既存の統合を壊してしまう可能性があります。
public_key = OpenSSL::PKey::RSA.new(params[:public_key])
@payload = Base64.encode64(public_key.public_encrypt(@payload, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING))
「いいね!」 3
@simon はい、これは間違いなくNode v22で問題を引き起こしています。セキュリティパッチを元に戻さないのは素晴らしいことです。API呼び出しまたはDiscourseのサイト設定でフラグを設定して、目的のパディングを選択できるようにすると良いでしょう。(そうすれば、既存のデフォルトを維持したい人もいるでしょう。)
「いいね!」 1
NodeRSA を使用して、ここにある手順に大まかに従うと機能します。
sam
(Sam Saffron)
5
OAEP は、CCA / Bleichenbach 攻撃に耐性のある新しいアプリケーションに推奨されていることは理解しています。Node が強制的に対応しなければならないのは少し残念ですが、これは「より大きな善」のためだと考えます。
これを Discourse 管理者が考慮しなければならないもう一つのトグルにすることは、悪夢なので、非常に懸念しています。
代わりに、Discourse Hub を修正して、新しい形式と古い形式を同時にサポートできるようにする必要があります。API が公開キーの「バージョン」を示すようなものが必要です。
これは、かなりの数のシステムにまたがる複雑な変更です。あなたが提案した修正は、Discourse Hub がそのモードに切り替えた管理者のために機能しなくなるため、問題を引き起こします。
「いいね!」 3
追加のコンテキストをありがとうございます。
はっきりさせておくと、これはローカル開発を行う際に問題となることがあります。しかし、私たちのリソースがAWS EC2インスタンスに展開されている場合は問題になりません。おそらく、彼らのNodeのバージョンには何らかの裏側のカスタマイズやバージョンがあり、暗号ライブラリにこの問題がないのだと思います。
pmusaraj
(Penar Musaraj)
8
いきなりですが、そのエラーは間違っているように思えます。これはNodeで削除された機能ではなく、一部のOpenSSLのインストールに関する問題です。Nodeのドキュメント(Crypto | Node.js v25.0.0 Documentation
crypto.privateDecrypt() で crypto.constants.RSA_PKCS1_PADDING を使用するには、OpenSSL が暗黙的な拒否(rsa_pkcs1_implicit_rejection)をサポートしている必要があります。
[Bug]: RSA_PKCS1_PADDING is no longer supported for private decryption · Issue #487 · bropat/eufy-security-client · GitHub も参照してください。
ローカルでテストしたところ、暗号化と復号の両方でパディングに crypto.constants.RSA_PKCS1_PADDING を使用するように切り替えても、これは機能します。An example of RSA Encryption implemented in Node.js · GitHub OpenSSL 3.4.0 および Node 23.6.1 を使用しています。
サイト設定を使用する際の難しい点は、クライアントが特定のインスタンスがどのパディングをサポートしているかを知ることができないことです。これにより、インスタンス/サービス間の互換性を理解するのが難しくなります。
既存の実装を明確にすること、つまり RSA_PKCS1_PADDING を使用していることを明示的に記載し、その後アップグレードを検討することをお勧めします。おそらく、このエンドポイントにバージョン管理を導入する必要があり、クライアントがそのバージョン以前/以降で適切なパディングをきれいに使用できるようになります。
「いいね!」 2
simon
9
参考のために、これは私のリクエストではなく、去年の6月に私が気づいた観察です。
「いいね!」 2