我需要连接客户端&服务器不受信任的网络。我考虑过使用TLS (crypto/tls),但据我所知,我首先需要创建一个crypto/x509.Certificate。但我觉得我需要传递给x509.CreateCertificate() function的所有参数都不知所措 - 它说它需要以下所有字段:
SerialNumber,Subject,NotBefore,NotAfter,KeyUsage,BasicConstraintsValid,IsCA,MaxPathLen,SubjectKeyId,DNSNames,PermittedDNSDomainsCritical,PermittedDNSDomains。
我可以完全控制两个端点,所以我相信我不需要任何过期或失效支持/参数(我可以随时在客户端和服务器上更改密钥) - 所以我可以跳过 NotBefore 和 NotAfter (?或者我是否必须设置它们?)。我应该在所有其他领域中放置什么,以及为什么要避免任何漏洞?另外,我可以使用相同的私钥/公钥对进行身份验证(客户端到服务器,服务器到客户端),还是必须使用2对?
或者,我可以使用比TLS更简单的东西吗?但请注意,我需要双向身份验证。
修改 的
我根据接受的答案中的建议以及generate_cert.go的密钥生成代码创建了一个简单的库 - 请参阅:
答案 0 :(得分:9)
Owlstead部分正确。您最好的选择是使用OpenSSL创建自签名证书。但是,我会使用Go TLS库进行加密。以下是一些可能对您有帮助的代码。
我通常按照here的说明操作。命令摘要(适用于客户端和服务器):
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
首先,创建一个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
答案 1 :(得分:0)
正如owlstead所说,TLS仍然是你最好的选择。可以通过以下在线指南来创建自己的证书。
以下文章允许您创建自己的SSL根证书(您有效地成为自己的根CA,如Verisign等)。通过此,您可以创建和签署自己的应用程序证书并进行分发。如果,如你所说,你可以完全控制两个终点,这可能值得一试。