Benutzer-API-Schlüssel sollten OAEP-Padding verwenden

Ein kleines und vielleicht ein größeres Problem:

Es gibt einen erforderlichen nonce-Parameter, der in der Dokumentation nicht erwähnt wird:

  def require_params
    %i[public_key nonce scopes client_id application_name].each { |p| params.require(p) }
  end

Nun zum kniffligeren Problem. Discourse ruft die Methode public_encrypt ohne Argumente auf:

Das bedeutet, dass das padding-Argument standardmäßig auf PKCS1_PADDING gesetzt wird. Laut der Ruby-Dokumentation:

Verschlüsselt string mit dem öffentlichen Schlüssel. padding ist standardmäßig PKCS1_PADDING, der als unsicher gilt, aber aus Gründen der Abwärtskompatibilität beibehalten wird.

Leider gibt Node v20.14.0 (die aktuelle LTS) einen Fehler zurück, wenn versucht wird, crypto.privateDecrypt mit RSA_PKCS1_PADDING aufzurufen:

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 is no longer supported for private decryption, this can be reverted with --security-revert=CVE-2023-46809

Eine mögliche Lösung für Node-Apps ist, Node mit dem unsicheren Flag auszuführen:

node --security-revert=CVE-2023-46809

Eine Behebung auf der Discourse-Seite wäre einfach, aber ich vermute, sie würde viele bestehende Integrationen unterbrechen:

public_key = OpenSSL::PKey::RSA.new(params[:public_key])
@payload = Base64.encode64(public_key.public_encrypt(@payload, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING))
3 „Gefällt mir“

@simon Ja, das verursacht definitiv Probleme mit Node v22. Es wäre großartig, keine Sicherheitspatches rückgängig machen zu müssen. Es wäre schön, ein Flag im API-Aufruf oder eine Website-Einstellung in Discourse festlegen zu können, um das gewünschte Padding auszuwählen. (Auf diese Weise können die Leute die bestehende Standardeinstellung beibehalten, wenn sie möchten.)

1 „Gefällt mir“

Das Befolgen der Schritte hier mit NodeRSA funktioniert ungefähr

Das scheint eine ziemlich einfache Ergänzung zu sein?

Ich verstehe, dass OAEP für neue Apps, die resistent gegen CCA/Bleichenbach-Angriffe sind, empfohlen wird. Dass Node uns hier unter Druck setzt, ist etwas traurig, aber ich schätze, das ist eine Art „höheres Gut“.

Ich bin äußerst besorgt darüber, dies zu einem weiteren Schalter für einen Discourse-Administrator zu machen, über den er nachdenken muss, das ist ein Albtraum.

Stattdessen müssten wir Discourse Hub reparieren, um die neuen und alten Varianten gleichzeitig zu unterstützen, und etwas in unserer API signalisieren, das die „Version“ des öffentlichen Schlüssels angibt.

Es ist eine komplizierte Änderung, die durch recht viele Systeme läuft. Die von Ihnen vorgeschlagene Korrektur ist ein Problem, da Discourse Hub dann für Administratoren, die in diesen Modus wechseln, nicht mehr funktioniert.

3 „Gefällt mir“

Vielen Dank für die zusätzlichen Informationen.

Um es klarzustellen, das ist ein Problem, das ich bei der lokalen Entwicklung habe. Aber wenn ich mich mit unseren auf AWS EC2-Instanzen bereitgestellten Ressourcen verbinde, ist es kein Problem. Ich vermute, ihre Version von Node enthält some Hinter-den-Kulissen-Anpassungen oder Versionierungen, bei denen die Crypto-Bibliothek dieses Problem nicht hat.

Ich komme hier kalt rein, aber dieser Fehler scheint falsch zu sein. Dies ist keine Funktion, die in Node entfernt wurde, sondern ein Problem mit einer OpenSSL-Installation. Laut den Node-Dokumenten:

Die Verwendung von crypto.constants.RSA_PKCS1_PADDING in crypto.privateDecrypt() erfordert, dass OpenSSL implizite Ablehnung unterstützt (rsa_pkcs1_implicit_rejection).

Siehe auch [Bug]: RSA_PKCS1_PADDING is no longer supported for private decryption · Issue #487 · bropat/eufy-security-client · GitHub

Beim lokalen Testen funktioniert dies für mich: An example of RSA Encryption implemented in Node.js · GitHub, auch wenn ich für das Padding sowohl für die Verschlüsselung als auch für die Entschlüsselung crypto.constants.RSA_PKCS1_PADDING verwende. Ich verwende OpenSSL 3.4.0 und Node 23.6.1.

Das Schwierige bei der Verwendung einer Site-Einstellung ist, dass Clients nicht wissen, welches Padding die spezifische Instanz unterstützt. Das erschwert das Verständnis der Kompatibilität zwischen Instanzen/Diensten.

Ich denke, wir sollten die bestehende Implementierung klären, d. h. explizit darauf hinweisen, dass wir RSA_PKCS1_PADDING verwenden, und dann über ein Upgrade nachdenken. Vielleicht müssen wir eine Versionierung für diesen Endpunkt einführen, damit Clients vor/nach dieser Version ordnungsgemäß das richtige Padding verwenden können.

2 „Gefällt mir“

Zum Kontext, dies ist keine Funktionsanfrage von mir, sondern nur eine Beobachtung, die ich im Juni des letzten Jahres gemacht habe.

2 „Gefällt mir“