web-dev-qa-db-ja.com

Golang-自己署名証明書を使用した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")

私の間違いは何ですか?

26
Zap

最終的にx509.CreateCertificateに組み込まれたgoで動作しました。問題はIsCA:trueフラグを設定しなかったx509.KeyUsageCertSignを設定しただけ自己署名証明書は機能しますが、証明書チェーンの検証中にクラッシュしました。

26
Zap

問題は、サーバー側の設定で [〜#〜] ca [〜#〜] 証明書が必要であり、このCAがサーバーの証明書に署名している必要があることです。

generate CA証明書となるGoコードをいくつか作成しましたが、これは誰にもレビューされておらず、主にクライアント証明書をいじるおもちゃです。最も安全な方法は、おそらく openssl ca 証明書を生成して署名します。基本的な手順は次のとおりです。

  1. CA証明書を生成する
  2. サーバーキーを生成する
  3. CA証明書でサーバーキーに署名する
  4. CA証明書をクライアントの tls.ConfigRootCAs
  5. サーバーのtls.Configサーバーキーと署名付き証明書。
10
Kyle Lemons

カイル、正しいです。このツールはあなたが望むことを行い、プロセス全体を簡素化します:

https://github.com/deckarep/EasyCert/releases (opensslツールを内部で使用するため、OSXのみがサポートされます)

およびソース:

https://github.com/deckarep/EasyCert

基本的にこのツールを使用すると、ファイルのバンドルが生成されますが、完了時に出力される3つが必要になります。

  1. cAルートcerファイル
  2. サーバーcerファイル
  3. サーバーキーファイル
4
Ralph Caraveo

Golangでmysqlクライアントを使用すると、同じエラーが表示されました。

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

InsecureSkipVerifytrueに設定すると(証明書の検証をスキップするため)解決されました:

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:I6qnD6zNDmqdDLXYg3HqVAk2P@tcp(10.111.202.229:3306)/ccp?tls=custom")
    defer db.Close()
}
1
Vikram Hosakote

私の場合、追加した証明書はpem形式で正しくエンコードされていません。 keytoolsを使用している場合、キーストアから証明書をエクスポートするときに-rfcを追加するようにしてください。エンコードされたpemはテキストエディターで開いて表示できます。

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

0
Mac

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
0
Francois