web-dev-qa-db-fra.com

Golang - TLS avec certificat auto-signé

J'essaie d'établir une connexion TLS avec l'utilisation d'un certificat de serveur auto-signé.

J'ai généré le certificat avec cet exemple de code: http://golang.org/src/pkg/crypto/tls/generate_cert.go

Mon code client pertinent ressemble à cela:

// server cert is self signed -> server_cert == ca_cert
CA_Pool := x509.NewCertPool()
severCert, err := ioutil.ReadFile("./cert.pem")
if err != nil {
    log.Fatal("Could not load server certificate!")
}
CA_Pool.AppendCertsFromPEM(severCert)

config := tls.Config{RootCAs: CA_Pool}

conn, err := tls.Dial("tcp", "127.0.0.1:8000", &config)
if err != nil {
    log.Fatalf("client: dial: %s", err)
}

Et le code de serveur pertinent comme ça:

cert, err := tls.LoadX509KeyPair("./cert.pem", "./key.pem")
config := tls.Config{Certificates: []tls.Certificate{cert}}
listener, err := tls.Listen("tcp", "127.0.0.1:8000", &config)

for {
    conn, err := listener.Accept()
    if err != nil {
        log.Printf("server: accept: %s", err)
        break
    }
    log.Printf("server: accepted from %s", conn.RemoteAddr())
    go handleConnection(conn)
}

Parce que le certificat de serveur est auto-signé, utilisez le même certificat pour le serveur et les clients CA_Pool, mais cela ne semble pas fonctionner car je reçois toujours cette erreur:

client: dial: x509: certificate signed by unknown authority 
(possibly because of "x509: invalid signature: parent certificate
cannot sign this kind of certificate" while trying to verify 
candidate authority certificate "serial:0")

Quelle est mon erreur?

24
Zap

Il a finalement fonctionné avec le go construit dans x509.CreateCertificate, Le problème était que je n’ai pas défini le drapeau IsCA: true , Je n’ai défini que le x509.KeyUsageCertSign qui a créé le certificat auto-signé fonctionne, mais s'est écrasé lors de la vérification de la chaîne de certificats.

24
Zap

Le problème est que vous avez besoin d'un certificat CA dans la configuration côté serveur et que cette autorité de certification doit avoir signé le certificat du serveur.

J'ai écrit un code Go qui va générer un certificat de CA, mais il n'a été examiné par personne et est principalement un jouet pour jouer avec les certificats de client. Le pari le plus sûr est probablement d'utiliser openssl ca pour générer et signer le certificat. Les étapes de base seront les suivantes:

  1. Générer un certificat de CA
  2. Générer une clé de serveur
  3. Signer la clé du serveur avec le certificat de l'autorité de certification
  4. Ajoutez le certificat de l'autorité de certification au tls.ConfigRootCAs du client
  5. Configurez le tls.Config du serveur avec la clé de serveur et le certificat signé.
9
Kyle Lemons

Kyle, est correct. Cet outil fera ce que vous voulez et simplifie tout le processus:

https://github.com/deckarep/EasyCert/releases (seul OSX est pris en charge car il utilise l'outil openssl en interne)

et la source:

https://github.com/deckarep/EasyCert

Fondamentalement, avec cet outil, il générera un ensemble de fichiers, mais vous aurez besoin des trois fichiers qu’il génère à la fin.

  1. un fichier cer racine de la CA
  2. un fichier cer Server
  3. un fichier de clé de serveur
4
Ralph Caraveo

J'ai vu la même erreur en utilisant le client mysql dans golang:

Failed to connect to database:  x509: cannot validate certificate for 10.111.202.229 because it doesn't contain any IP SANs

et régler InsecureSkipVerify sur true (pour ignorer la vérification du certificat) a résolu le problème pour moi:

https://godoc.org/crypto/tls#Config

Le code suivant a fonctionné pour moi:

package main

import (
 "fmt"
 "github.com/go-sql-driver/mysql"
 "github.com/jinzhu/gorm"
 "crypto/tls"
 "crypto/x509"
 "io/ioutil"
 "log"
)

func main() {
    rootCertPool := x509.NewCertPool()
    pem, err := ioutil.ReadFile("/usr/local/share/ca-certificates/ccp-root-ca.crt")
    if err != nil {
            log.Fatal(err)
    }
    if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
        log.Fatal("Failed to append root CA cert at /usr/local/share/ca-certificates/ccp-root-ca.crt.")
    }
    mysql.RegisterTLSConfig("custom", &tls.Config{
        RootCAs: rootCertPool,
        InsecureSkipVerify: true,
    })

    db, err := gorm.Open("mysql", "ccp-user:I6qnD6zNDmqdDLXYg3HqVAk2P@tcp(10.111.202.229:3306)/ccp?tls=custom")
    defer db.Close()
}
0
Vikram Hosakote