Подтвердить что ты не робот

TLS с подписанным сертификатом

Я пытаюсь установить соединение TLS с использованием сертификата самоподписанного сервера.

Я сгенерировал сертификат с помощью этого примера кода: http://golang.org/src/pkg/crypto/tls/generate_cert.go

Мой соответствующий код клиента выглядит следующим образом:

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

И соответствующий серверный код:

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

Поскольку сертификат сервера сам подписан, используется тот же сертификат для сервера и клиентов CA_Pool, однако это не работает, поскольку я всегда получаю эту ошибку:

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

Какая моя ошибка?

4b9b3361

Ответ 1

Наконец, он работал с ходом, созданным в x509.CreateCertificate, проблема заключалась в том, что я не установил IsCA: флаг истины, Я установил только x509.KeyUsageCertSign, который сделал создание самостоятельной работы сертификата, но сработал при проверке цепочки сертификатов.

Ответ 2

Проблема в том, что вам нужен сертификат CA в конфигурации на стороне сервера, и этот ЦС должен был подписывать сертификат сервера.

Я написал код Go, который будет генерировать сертификат CA, но он не был просмотрен кем-либо и в основном является игрушкой для игры с сертификатами клиентов, Самая безопасная ставка, вероятно, должна использоваться openssl ca для создания и подписания сертификата. Основные шаги:

  • Создание сертификата CA
  • Создать ключ сервера
  • Подпишите ключ сервера с сертификатом CA
  • Добавить сертификат CA клиенту tls.Config RootCAs
  • Настройте сервер tls.Config ключом сервера и подписанным сертификатом.

Ответ 3

Кайл, верно. Этот инструмент будет делать то, что вы хотите, и упрощает весь процесс:

https://github.com/deckarep/EasyCert/releases (поддерживается только OSX, так как он использует инструмент openssl внутри)

и источник:

https://github.com/deckarep/EasyCert

В основном с помощью этого инструмента он будет генерировать набор файлов, но вам понадобятся три, которые он выдает, когда это будет сделано.

  • файл корневого сервера CA
  • Серверный файл
  • ключевой файл сервера

Ответ 4

Я видел ту же ошибку при использовании клиента MySQL в Go:

Failed to connect to database:  x509: cannot validate certificate for 10.111.202.229 because it does not contain any IP SANs

и установка InsecureSkipVerify на true (чтобы пропустить проверку сертификата) решила его для меня:

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

У меня работает следующий код:

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:[email protected](10.111.202.229:3306)/ccp?tls=custom")
    defer db.Close()
}

Ответ 5

Вам нужно использовать флаг InsecureSkipVerify, см. https://groups.google.com/forum/#!topic/golang-nuts/c9zEiH6ixyw.

Связанный код этого сообщения (если страница недоступна):

smtpbox := "mail.foo.com:25"
c, err := smtp.Dial(smtpbox)

host, _, _ := net.SplitHostPort(smtpbox)
tlc := &tls.Config{
    InsecureSkipVerify: true,
    ServerName:         host,
}
if err = c.StartTLS(tlc); err != nil {
    fmt.Printf(err)
    os.Exit(1)
} 
// carry on with rest of smtp transaction 
// c.Auth, c.Mail, c.Rcpt, c.Data, etc

Ответ 6

В моем случае добавленный сертификат не был правильно закодирован в формате pem. Если вы используете keytools, обязательно добавьте -rfc при экспорте сертификата из хранилища ключей, закодированный pem можно открыть в текстовом редакторе для отображения:

-----BEGIN CERTIFICATE----- MIIDiDCCAnCgAwIBAgIEHKSkvDANBgkqhkiG9w0BAQsFADBi...