通过不安全的网络轻松安全连接(两个端点完全受控)

时间:2012-09-02 20:37:15

标签: security authentication encryption network-programming go

我需要连接客户端&服务器不受信任的网络。我考虑过使用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的密钥生成代码创建了一个简单的库 - 请参阅:

  

github.com/akavel/tunnel

2 个答案:

答案 0 :(得分:9)

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

创建x509密钥对

我通常按照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

使用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

答案 1 :(得分:0)

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

以下文章允许您创建自己的SSL根证书(您有效地成为自己的根CA,如Verisign等)。通过此,您可以创建和签署自己的应用程序证书并进行分发。如果,如你所说,你可以完全控制两个终点,这可能值得一试。

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