Wie kann man einen Server dazu zwingen, eine bestimmte elliptische Kurve am Anfang des Handshakes über openssl zu verwenden?

4173
SmithCorner

Gibt es eine Möglichkeit oder einen Befehl in openssl, um einen Server zu zwingen, eine bestimmte elliptische Kurve zu verwenden, die ich mit einem Zertifikat oder einem Schlüssel anfordert? Kann ich den Prozess "fragen", welche Kurven er verwenden kann?

4
Sie können in einer Konfigurationsdatei angeben user45475 vor 8 Jahren 0
Du meinst für ECDHE? StackzOfZtuff vor 8 Jahren 0
Ja. Es sollte für den Schlüsselaustausch verwendet werden. Es ist auch nur ECDH möglich. vor 8 Jahren 0

2 Antworten auf die Frage

5
dave_thompson_085

Ihre Frage ist mehrdeutig und die Antworten sind sehr unterschiedlich.

Protokoll. Die Unterstützungskurvenerweiterung in der ClientHello-Nachricht gibt die Kurven an (Standard / Named oder 'explizite' GF (2 ^ k) oder GF (p)), die der Client für die Verwendung des Servers bereit ist. Wenn mehr als eine angegeben ist, kann der Server eine davon auswählen. Wenn es einen Wert angibt, kann der Server nur diesen verwenden. Wenn der Server die oder eine bestimmte Kurve nicht unterstützt, kann bei der Aushandlung keine EC-Suite ausgewählt werden. Wenn andere Suiten nicht von beiden Seiten unterstützt werden und von beiden Seiten akzeptiert werden, schlägt die Verhandlung fehl.

OpenSSL-Client an einen beliebigen Server über 1.0.1 sendet diese Erweiterung immer, um alle benannten Kurven (in rfc4492) und keine expliziten Kurven zuzulassen. Abgesehen von RedHat (AFAIK noch?) Sind die OpenSSL-Versionen nur für P-256, P-384 und P-521 verfügbar. 1.0.2 fügt neue API-Aufrufe hinzu, um diese Erweiterung zu steuern, siehe https://www.openssl.org/docs/ssl/SSL_CTX_set1_curves_list.html . Entweder Code und Build für Ihr Client-Programm gegen 1.0.2 * und nicht für RedHat, oder holen Sie sich heraus, wer das Client-Programm betreut.

Beliebiger Client an OpenSSL-Server für ECDHE. OpenSSL-Server bis 1.0.1 können vor dem Handshake konfiguriert werden, entweder für alle Verbindungen, die sich eine SSL_CTX teilen, oder für jede SSL-Verbindung separat, mit ECDHE-"temporären Parametern", die die Kurve sind (sind?). Für den Schlüsselaustausch wird nur die konfigurierte Kurve verwendet. Für ECDHE-ECDSA kann der im Authentic (mit dem dazugehörigen privaten Schlüssel) zur Authentifizierung verwendete Zertifikat einen anderen verwendenKurve; Dieser Schlüssel und diese Kurve wurden ausgewählt, bevor das Zertifikat ausgestellt und von der Zertifizierungsstelle "genehmigt" wurde. Sie können jetzt nicht geändert werden, während die "temporäre" ECDHE-Auswahl durch den Servercode oder die Konfiguration getroffen wird. Wenn entweder die "Temp" -Kurve oder die Zertifizierungskurve, wenn das Zertifikat ECC ist, nicht in der vom Client zugelassenen Liste enthalten ist, können ECDHE oder ECDHE-ECDSA nicht ausgehandelt werden.

Anstatt vorab zu konfigurieren, kann der Server einen Rückruf festlegen, der von der OpenSSL-Bibliothek aufgerufen wird, um die ECDHE-Kurve (oder den Schlüssel) für einen bestimmten Handshake auszuwählen. Dies sollte eine Kurve wählen, die für den Client akzeptabel ist, es sei denn, dies ist für den Server nicht akzeptabel. Auch für ECDHE-ECDSA kann die Kurve im Zertifikat für die Authentifizierung anders sein, wurde bereits vor der Ausgabe ausgewählt und kann nicht geändert werden. Wenn dies für den Kunden nicht akzeptabel ist, kann dies nicht ausgehandelt werden. Neu in 1.0.2 ist die Option, dass OpenSSL automatisch eine ECDHE-Kurve auswählen kann, die für den Client akzeptabel ist, während die Authentifizierungsstärke angepasst wird.

Beim Server für statische ECDH ist die Kurve (und der Schlüssel), die für den Schlüsselaustausch verwendet wird, diejenige im Zertifikat, die wie oben vor der Ausstellung des Zertifikats ausgewählt wurde und nicht geändert werden kann. Wenn diese Kurve für den Kunden nicht akzeptabel ist, kann ECDH nicht ausgehandelt werden.

2
jww

Gibt es eine Möglichkeit oder einen Befehl in openssl, um einen Server zu zwingen, eine bestimmte elliptische Kurve zu verwenden

Im Allgemeinen bin ich nicht sicher, wie ich dies über eine CONF-Datei erledigen kann. Die SSL_CONF_*API-Aufrufe (siehe unten) scheinen darauf hinzuweisen, dass sie Teil einer Konfigurationsdatei sein können. Aber ich habe es noch nie gemacht.


Wie kann man einen Server dazu zwingen, eine bestimmte elliptische Kurve am Anfang des Handshakes über openssl zu verwenden?

Sie können, aber Sie müssen Ihre Quellen ändern. Hier ist von einem der OpenSSL-Entwickler in einer privaten E-Mail. Ich bin nicht sicher, ob es in der Praxis funktioniert, weil ich die unten beschriebene Patch-Methode verwende.

Under 0.9.x: int nid = OBJ_sn2nid(named_curve); ecdh = EC_KEY_new_by_curve_name(nid); SSL_CTX_set_tmp_ecdh(ctx,ecdh); EC_KEY_free(ecdh);  Under 1.x: SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); SSL_CONF_cmd(cctx, "-named_curve", "P-256"); SSL_CONF_CTX_finish(cctx); 

Für 1.0.1 und darunter können Sie die Quellen in ändern t1_lib.c. Insbesondere finden ssl_prepare_clienthello_tlsextund pref_listund ändern Sie es zu dem, was Sie wollen. So sieht es standardmäßig aus:

static int pref_list[] = { NID_sect571r1, /* sect571r1 (14) */ NID_sect571k1, /* sect571k1 (13) */ NID_secp521r1, /* secp521r1 (25) */ NID_sect409k1, /* sect409k1 (11) */ NID_sect409r1, /* sect409r1 (12) */ NID_secp384r1, /* secp384r1 (24) */ NID_sect283k1, /* sect283k1 (9) */ NID_sect283r1, /* sect283r1 (10) */ NID_secp256k1, /* secp256k1 (22) */ NID_X9_62_prime256v1, /* secp256r1 (23) */ NID_sect239k1, /* sect239k1 (8) */ NID_sect233k1, /* sect233k1 (6) */ NID_sect233r1, /* sect233r1 (7) */ NID_secp224k1, /* secp224k1 (20) */ NID_secp224r1, /* secp224r1 (21) */ }; 

Siehe auch Problem Nr. 3179: Funktionsanforderung: Festlegen der Liste der Voreinstellungen für EC-Kurven im Client .


Für OpenSSL 1.0.2 und höher können Sie verwenden SSL_CTX_set1_curves. pref_listist beim grepping der Quellen nicht mehr vorhanden.