it-swarm.com.de

Wie mache ich eine https-Anfrage mit falschem Zertifikat?

Angenommen, ich möchte https://golang.org programmgesteuert erhalten. Derzeit hat golang.org (ssl) ein fehlerhaftes Zertifikat, das an *.appspot.com ausgestellt wurde. Wenn ich also Folgendes ausführen:

package main

import (
    "log"
    "net/http"
)

func main() {
    _, err := http.Get("https://golang.org/")
    if err != nil {
        log.Fatal(err)
    }
}

Ich bekomme (wie erwartet)

Get https://golang.org/: certificate is valid for *.appspot.com, *.*.appspot.com, appspot.com, not golang.org

Nun möchte ich diesem Zertifikat selbst vertrauen (stellen Sie sich ein selbst ausgestelltes Zertifikat vor, bei dem ich den Fingerabdruck überprüfen kann usw.): Wie kann ich eine Anfrage stellen und das Zertifikat validieren/vertrauen?

Ich muss wahrscheinlich openssl verwenden, um das Zertifikat herunterzuladen, es in meine Datei zu laden und tls.Config struct! Auszufüllen.

93
topskip

Sicherheitshinweis: Das Deaktivieren von Sicherheitsprüfungen ist gefährlich und sollte vermieden werden

Sie können Sicherheitsüberprüfungen global für alle Anforderungen des Standardclients deaktivieren:

package main

import (
    "fmt"
    "net/http"
    "crypto/tls"
)

func main() {
    http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
    _, err := http.Get("https://golang.org/")
    if err != nil {
        fmt.Println(err)
    }
}

Sie können die Sicherheitsüberprüfung für einen Client deaktivieren:

package main

import (
    "fmt"
    "net/http"
    "crypto/tls"
)

func main() {
    tr := &http.Transport{
        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
    }
    client := &http.Client{Transport: tr}
    _, err := client.Get("https://golang.org/")
    if err != nil {
        fmt.Println(err)
    }
}
204
cyberdelia

Hier ist eine Möglichkeit, dies zu tun, ohne die Standardeinstellungen von DefaultTransport zu verlieren und ohne die gefälschte Anforderung als Kommentar zu benötigen.

defaultTransport := http.DefaultTransport.(*http.Transport)

// Create new Transport that ignores self-signed SSL
httpClientWithSelfSignedTLS := &http.Transport{
  Proxy:                 defaultTransport.Proxy,
  DialContext:           defaultTransport.DialContext,
  MaxIdleConns:          defaultTransport.MaxIdleConns,
  IdleConnTimeout:       defaultTransport.IdleConnTimeout,
  ExpectContinueTimeout: defaultTransport.ExpectContinueTimeout,
  TLSHandshakeTimeout:   defaultTransport.TLSHandshakeTimeout,
  TLSClientConfig:       &tls.Config{InsecureSkipVerify: true},
}
13
Jonathan Lin

Alle diese Antworten sind falsch! Verwenden Sie InsecureSkipVerify nicht für einen CN, der nicht mit dem Hostnamen übereinstimmt. Die Go-Entwickler waren unklug darauf, die Überprüfung des Hostnamens nicht zu deaktivieren (was legitime Zwecke hat - Tunnel, Nats, Shared-Cluster-Zertifikate usw.). Außerdem hatten sie etwas, das ähnlich aussieht, aber vollständig die Zertifikatprüfung ignoriert. Sie müssen wissen, dass das Zertifikat gültig und von einem vertrauenswürdigen Zertifikat signiert ist. In gewöhnlichen Szenarien wissen Sie jedoch, dass der CN nicht mit dem Hostnamen übereinstimmt, mit dem Sie verbunden sind. Für diese setzen Sie ServerName auf tls.Config. Wenn tls.Config.ServerName == remoteServerCN, ist die Zertifikatprüfung erfolgreich. Das ist, was du willst. InsecureSkipVerify bedeutet, dass es KEINE Authentifizierung gibt. und es ist reif für einen Mann in der Mitte; den Zweck der Verwendung von TLS zu vereiteln.

Es gibt eine legitime Verwendung für InsecureSkipVerify: Verwenden Sie diese Option, um eine Verbindung zu einem Host herzustellen und das Zertifikat zu packen. Trennen Sie dann sofort die Verbindung. Wenn Sie Ihren Code für die Verwendung von InsecureSkipVerify einrichten, ist dies im Allgemeinen darauf zurückzuführen, dass Sie ServerName nicht ordnungsgemäß festgelegt haben (er muss von einer Umgebungsvariable oder etwas anderem stammen.

Insbesondere wenn Sie Client-Zertifikate verwenden und sich bei der Authentifizierung darauf verlassen, haben Sie im Grunde eine falsche Anmeldung, die sich eigentlich nicht mehr anmeldet. Lehnen Sie den Code ab, der InsecureSkipVerify macht, oder Sie werden auf harte Weise lernen, was daran falsch ist!

8
Rob

Wenn Sie die Standardeinstellungen aus dem http-Paket verwenden möchten und kein neues Transport- und Client-Objekt erstellen müssen, können Sie die Zertifikatüberprüfung wie folgt ignorieren:

tr := http.DefaultTransport.(*http.Transport)
tr.TLSClientConfig.InsecureSkipVerify = true
7
Cornel Damian

Im Allgemeinen muss die DNS-Domäne der URL mit dem Zertifikatbetreff des Zertifikats übereinstimmen.

In früheren Zeiten könnte dies entweder durch Festlegen der Domäne als cn des Zertifikats oder durch Festlegen der Domäne als alternativer Antragstellername erfolgen. 

Die Unterstützung für cn war lange Zeit (seit 2000 in RFC 2818 ) veraltet, und der Chrome-Browser wird nicht einmal mehr auf die cn schauen. Daher müssen Sie heute die DNS-Domäne der URL als alternativen Antragstellernamen verwenden .

RFC 6125 verbietet die Überprüfung des cn, wenn SAN für DNS-Domäne vorhanden ist, nicht jedoch, wenn SAN für IP-Adresse vorhanden ist. RFC 6125 wiederholt auch, dass cn veraltet ist, was bereits in RFC 2818 gesagt wurde. Außerdem soll das Browserforum der Zertifizierungsstelle vorhanden sein, was in Kombination mit RFC 6125 im Wesentlichen bedeutet, dass cn niemals auf DNS-Domänennamen überprüft wird.

0
jwilleke