5

信頼できないネットワークを介してクライアントとサーバーを接続する必要があります。TLS (crypto/tls)の使用を検討しましたが、私が理解していることから、最初に create a crypto/x509.Certificateを作成する必要があります。しかし、 x509.CreateCertificate() 関数に渡す必要があるすべてのパラメーターに圧倒されます。次のすべてのフィールドが必要であると書かれています。

SerialNumber、Subject、NotBefore、NotAfter、KeyUsage、BasicConstraintsValid、IsCA、MaxPathLen、SubjectKeyId、DNSNames、PermittedDNSDomainsCritical、PermittedDNSDomains。

私は両方のエンドポイントを完全に制御できるので、有効期限や無効化のサポート/パラメーターは必要ないと思います (クライアントとサーバーの両方でいつでもキーを変更できます) - したがって、おそらくNotBeforeNotAfter (?またはとにかくそれらを設定する必要がありますか?)。脆弱性を回避するには、他のすべてのフィールドに何を入力する必要がありますか? また、その理由は何ですか? また、両方の認証方法 (クライアントからサーバーへ、およびサーバーからクライアントへ) に同じ秘密鍵/公開鍵のペアを使用できますか? それとも 2 つのペアを使用する必要がありますか?

または、TLS よりも簡単に使用できるものはありますか? ただし、双方向認証が必要であることに注意してください。

編集:

受け入れられた回答からの提案に加えて、 generate_cert.goからのキー生成コードに基づいて単純なライブラリを作成しました-参照:

github.com/akavel/トンネル

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ます。1 つの 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 ルート証明書を作成できます (Verisign などのように、事実上独自のルート CA になります)。これにより、独自のアプリケーション証明書を作成して署名し、配布することができます。あなたが言うように、両方のエンドポイントを完全に制御できる場合、これはおそらくチェックインする価値があります.

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

于 2012-09-02T21:57:37.863 に答える