5

我需要通过不受信任的网络连接客户端和服务器。我考虑过使用TLS (crypto/tls),但据我了解,我首先需要创建一个 create a crypto/x509.Certificate。但是我对需要传递给x509.CreateCertificate() 函数的所有参数感到不知所措——它说它需要以下所有字段:

序列号、主题、NotBefore、NotAfter、KeyUsage、BasicConstraintsValid、IsCA、MaxPathLen、SubjectKeyId、DNSNames、PermittedDNSDomainsCritical、PermittedDNSDomains。

我可以完全控制两个端点,所以我相信我不需要任何过期或失效支持/参数(我可以随时更改客户端和服务器上的密钥) - 所以我可以跳过NotBeforeNotAfter(?还是我必须设置它们?)。我应该在所有其他字段中添加什么,为什么要避免任何漏洞?另外,我可以使用相同的私钥/公钥对进行两种身份验证(客户端到服务器,服务器到客户端),还是必须使用 2 对?

或者,我可以使用比 TLS 更简单的东西吗?但是请注意,我需要进行两种身份验证。

编辑:

我根据接受的答案中的建议以及 generate_cert.go 中的密钥生成代码创建了一个简单的库-请参阅:

github.com/akavel/tunnel

4

2 回答 2

9

Owlstead 部分正确。您最好的选择是使用 OpenSSL 创建自签名证书。但是,我会使用 Go TLS 库进行加密。以下是一些可能对您有所帮助的代码。

创建 x509 密钥对

我通常按​​照这里的说明进行操作。命令摘要(对客户端和服务器都执行):

openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

使用 Go 的 TLS 库

首先,创建一个tls.Config. 一个 TLS 配置适用于客户端和服务器,但一些选项只需要在其中一个上设置:

cert, err := tls.LoadX509KeyPair(cert, key)
config := &tls.Config{
    Certificates: []Certificates{cert},
    ClientAuth: tls.RequireAnyClientCert, // Must be done on server
    InsecureSkipVerify: true, // Must be done on client
}

在服务器上,您需要设置一个 TLS 侦听器。这将其设置在端口 4443 上:

listener, err := tls.Listen("tcp", ":4443", config)
for {
    conn, err := listener.Accept()
    acceptConn(conn) // your code
}

在客户端:

conn, err := tls.Dial("tcp", serverAddr, config)

这将创建一个加密连接,但它不会验证对方是他们所说的人。最简单的方法是为每台服务器提供另一台服务器的公钥,并将其与刚刚连接的服务器进行比较。要在另一台服务器上查找公钥,您需要:

c := conn.(*tls.Conn) // convert net.Conn from listener to tls conn
err := c.Handshake() // ensure handshake is completed without error
state := c.ConnectionState()
pubKey, err := x509.MarshalPKIXPublicKey(state.PeerCertificates[0])
bytes.Equal(pubKey, knownKey) // compare to known value
于 2012-09-02T22:11:37.527 回答
0

正如 owlstead 所说,TLS 仍然是您最好的选择。可以通过遵循一些在线指南来创建自己的证书。

下面的文章让您创建自己的 SSL 根证书(您实际上成为自己的根 CA,如 Verisign 等)。有了这个,您可以创建和签署您自己的应用程序证书并分发它们。如果如您所说,您可以完全控制两个端点,那么这可能值得一试。

http://www.eclectica.ca/howto/ssl-cert-howto.php/

于 2012-09-02T21:57:37.863 回答