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")
Какая моя ошибка?
Ответы
Ответ 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...