2014-03-26 55 views
23

我正在嘗試使用自簽名服務器證書建立TLS連接。Golang - 帶有自簽名證書的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_P使用相同的證書但是,這似乎並沒有工作,因爲我總是得到這個錯誤:

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

我的錯誤是什麼?

回答

21

它終於用GO內置x509.CreateCertificate工作, 問題是,我沒有設置IsCA:真旗, 我只設置了x509。KeyUsageCertSign創建自簽名證書的工作,但驗證證書鏈時崩潰。

9

問題是,您需要在服務器端配置中使用CA證書,並且此CA必須對服務器的證書進行簽名。

我已經寫了一些Go代碼,將generate一個CA證書,但它沒有被任何人審查,並且大多是一個玩弄客戶端證書的玩具。最安全的賭注可能是使用openssl ca來生成和簽署證書。基本步驟是:

  1. 生成CA證書
  2. 生成服務器密鑰
  3. 標誌的CA證書
  4. 添加CA證書到客戶端的tls.ConfigRootCAs
  5. 設置服務器密鑰使用服務器密鑰和簽名證書將服務器的tls.Config更新。
4

凱爾,是正確的。該工具會做你想要什麼,它簡化了整個過程:

https://github.com/deckarep/EasyCert

基本上是:

https://github.com/deckarep/EasyCert/releases

和源(僅OSX是因爲它內部使用OpenSSL的工具支持)使用這個工具它會生成一捆文件,但是當它完成時你將需要它輸出的三個文件。

  1. 一個CA根CER文件
  2. 服務器CER文件
  3. 服務器密鑰文件
+0

OK,我用EasyCert但現在我得到一個:「客戶:撥打:X509:無法爲127.0.0.1,因爲驗證證書它不包含任何IP SAN「什麼是ISAN – Zap

+0

我要在這裏肢解並說你可能會在Go中遇到一個錯誤:https://code.google.com/p/go/issues/detail?id = 4658也許嘗試升級您的Go版本,如果可能的話。 –

0

您需要使用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 
+18

您應該驗證SSL證書而不是僅接受任何SSL證書。 – Pwnna

+5

這是一個測試的重要解決方法,真的幫助我瞭解。謝謝! – jaten

+1

InsecureSkipVerify表示「安全=關閉」。這使你受到MITM攻擊。這對發展是安全的! –