2014-03-26 54 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攻击。这对发展是安全的! –