简体   繁体   中英

Easy secure connection over unsafe network (both endpoints fully controlled)

I need to connect client & server over untrusted network. I've considered using TLS (crypto/tls) , but from what I understand, I first need to create a create a crypto/x509.Certificate . But I feel overwhelmed by all the parameters I need to pass to the x509.CreateCertificate() function - it says it needs all of the following fields:

SerialNumber, Subject, NotBefore, NotAfter, KeyUsage, BasicConstraintsValid, IsCA, MaxPathLen, SubjectKeyId, DNSNames, PermittedDNSDomainsCritical, PermittedDNSDomains.

I have full control over both endpoints, so I believe I don't need any expiration or invalidation support/parameters (I can change keys both on client and server at any time I want) - so I can probably skip NotBefore and NotAfter (? or do I have to set them anyway?). What should I put in all the other fields, and why, to avoid any vulnerabilities? Also, can I use the same private/public key pair for both ways authentication (client to server, and server to client), or do I have to use 2 pairs?

Or, is there something simpler than TLS that I could use? Note however, that I need to two way authentication.

EDIT:

I created a simple library based on suggestions from the accepted answer, plus key generation code from generate_cert.go - see:

github.com/akavel/tunnel

Owlstead is partly correct. Your best bet is creating self signed certificates using OpenSSL. However, I would then use the Go TLS library for encryption. Below is some code that may help you.

Creating an x509 key pair

I normally follow the instructions here . Summary of commands (do for both client and server):

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

Using Go's TLS library

First, create a tls.Config . One TLS config will work on both client and server but some of the options only need to be set on one or the other:

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
}

On the server, you need to setup a TLS listener. This sets it up on port 4443:

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

On the client:

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

This will create an encrypted connection, but it will not verify the other side is who they say they are. The easiest way to do that is to give each server the public key of the other server and compare it to the server that has just connected. To find the public key on the other server, you need to:

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

As owlstead stated, TLS is still your best bet. Creating your own certificates can be done by following some online guide.

The following article lets you create your own SSL root certificate (You effectively become your own Root CA, like Verisign and such). With this, you can create and sign your own application certificates and distribute them. If, as you say, you have full control over both end points, this is probably worth checking in to.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM