¿Cómo hacer una solicitud https con un certificado incorrecto?

Resuelto topskip asked hace 12 años • 6 respuestas

Digamos que quiero hacerlo https://golang.orgprogramáticamente. Actualmente golang.org (ssl) tiene un certificado incorrecto que se emite para *.appspot.comEntonces, cuando ejecuto esto:

package main

import (
    "log"
    "net/http"
)

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

Entiendo (como esperaba)

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

Ahora, quiero confiar en este certificado yo mismo (imagínese un certificado autoemitido donde puedo validar la huella digital, etc.): ¿cómo puedo realizar una solicitud y validar/confiar en el certificado?

Probablemente necesite usar openssl para descargar el certificado, cargarlo en mi archivo y completar tls.Configla estructura.

topskip avatar Aug 25 '12 19:08 topskip
Aceptado

Nota de seguridad: deshabilitar los controles de seguridad es peligroso y debe evitarse

Puede desactivar las comprobaciones de seguridad globalmente para todas las solicitudes del cliente predeterminado:

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)
    }
}

Puede desactivar la verificación de seguridad para un cliente:

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)
    }
}
cyberdelia avatar Aug 25 '2012 14:08 cyberdelia

Forma correcta (a partir de Go 1.13) (proporcionada por la respuesta a continuación ):

customTransport := http.DefaultTransport.(*http.Transport).Clone()
customTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
client := &http.Client{Transport: customTransport}

Respuesta original:

Aquí hay una manera de hacerlo sin perder la configuración predeterminada de DefaultTransporty sin necesitar la solicitud falsa según el comentario del usuario.

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

// Create new Transport that ignores self-signed SSL
customTransport := &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},
}
client := &http.Client{Transport: customTransport}

Manera más corta:

customTransport := &(*http.DefaultTransport.(*http.Transport)) // make shallow copy
customTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
client := &http.Client{Transport: customTransport}

Advertencia : solo para fines de prueba/desarrollo. ¡¡¡Cualquier otra cosa, procede bajo tu propia responsabilidad!!!

Jonathan Lin avatar Sep 02 '2017 07:09 Jonathan Lin

¡Todas estas respuestas están equivocadas! No lo utilice InsecureSkipVerifypara tratar con un CN que no coincida con el nombre de host. Los desarrolladores de Go, imprudentemente, se mostraron firmes en no deshabilitar las comprobaciones de nombres de host (que tienen usos legítimos: túneles, nats, certificados de clúster compartido, etc.), y al mismo tiempo tenían algo que parece similar pero que en realidad ignora por completo la verificación de certificados. Debe saber que el certificado es válido y está firmado por un certificado de confianza. Pero en escenarios comunes, usted sabe que el CN ​​no coincidirá con el nombre de host con el que se conectó. Para aquellos, opte ServerNamepor tls.Config. Si tls.Config.ServerName== remoteServerCN, la verificación del certificado se realizará correctamente. Esto es lo que quieres. InsecureSkipVerifysignifica que NO hay autenticación; y está listo para un hombre en el medio; frustrando el propósito de usar TLS.

Hay un uso legítimo para InsecureSkipVerify: usarlo para conectarse a un host y obtener su certificado, luego desconectarse inmediatamente. Si configura su código para usar InsecureSkipVerify, generalmente es porque no lo configuró ServerNamecorrectamente (deberá provenir de una var env o algo así; no se preocupe por este requisito... hágalo correctamente).

En particular, si utiliza certificados de cliente y confía en ellos para la autenticación, básicamente tiene un inicio de sesión falso que en realidad ya no inicia sesión. ¡Rechaza el código que sí lo hace InsecureSkipVerify, o aprenderás qué tiene de malo de la manera más difícil!

Rob avatar Nov 08 '2017 01:11 Rob

Si desea utilizar la configuración predeterminada del paquete http, por lo que no necesita crear un nuevo objeto de Transporte y Cliente, puede cambiar para ignorar la verificación del certificado de esta manera:

tr := http.DefaultTransport.(*http.Transport)
tr.TLSClientConfig.InsecureSkipVerify = true
Cornel Damian avatar Jan 20 '2017 15:01 Cornel Damian