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?
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.
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:
tls.Config
RootCAs
du clienttls.Config
du serveur avec la clé de serveur et le certificat signé.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.
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()
}