2016-07-27 10 views
1

私はシンプルなRSA暗号化チャットアプリケーションを作ろうとしてきました。私が遭遇した問題は、net.Connのように、TCP接続を介してrsa公開鍵を送信する必要があるということです。私の知る限り、タイプ[]バイトしか受け入れません。goでrsa.PublicKeyをtcp接続経由で送信するにはどうすればよいですか?

問題のコード

conn.Write([]byte(public_key)) 

これは私のcomplications.Thisコードを生成されたコードは、関数のhandleRequest下です。私はconn.Writeがタイプ[]バイトしか受け入れることができないことを理解していますが、これはどこにでもあります。 public_keyをクライアントにどのように配信できますか?私はすべてのサーバーコードをちょうどの場合に含めました。また、すべてのサーバー/クライアントコードコメントを取得したい場合は、githubリンクを作成します。ありがとう

念サーバーコードで

main.go

package main 

import (
    "fmt" 
    "github.com/jonfk/golang-chat/tcp/common" 
    "io" 
    "log" 
    "net" 
    "os" 
) 

const (
    CONN_HOST = "0.0.0.0" 
    CONN_PORT = "3333" 
    CONN_TYPE = "tcp" 
) 

var (
    connections []net.Conn 
) 

func main() { 
    setUP(3072) 
    l, err := net.Listen(CONN_TYPE, CONN_HOST+":"+CONN_PORT) 
    if err != nil { 
     fmt.Println("Error listening:", err.Error()) 
     os.Exit(1) 
    } 
    // Close the listener when the application closes. 
    defer l.Close() 
    fmt.Println("Listening on " + CONN_HOST + ":" + CONN_PORT) 
    for { 
     // Listen for an incoming connection. 
     conn, err := l.Accept() 
     if err != nil { 
      fmt.Println("Error accepting: ", err.Error()) 
      os.Exit(1) 
     } 
     // Save connection 
     connections = append(connections, conn) 
     // Handle connections in a new goroutine. 
     go handleRequest(conn) 
    } 
} 

// Handles incoming requests. 
func handleRequest(conn net.Conn) { 
    //I use the common library but this is how it would look like using go's net library. 
    conn.Write([]byte(public_key)) 
    //Using the import common library this is what the command would be 
    //common.WriteMsg(conn,string(public_key)) 
    for { 
     msg, err := common.ReadMsg(conn) 
     if err != nil { 
      if err == io.EOF { 
       // Close the connection when you're done with it. 
       removeConn(conn) 
       conn.Close() 
       return 
      } 
      log.Println(err) 
      return 
     } 
     broadcast(conn, msg) 
    } 
} 

func removeConn(conn net.Conn) { 
    var i int 
    for i = range connections { 
     if connections[i] == conn { 
      break 
     } 
    } 
    connections = append(connections[:i], connections[i+1:]...) 
} 

func broadcast(conn net.Conn, msg string) { 
    for i := range connections { 
     if connections[i] != conn { 
      err := common.WriteMsg(connections[i], msg) 
      if err != nil { 
       log.Println(err) 
      } 
     } 
    } 
} 

encryption.go

package main 
import (
    "crypto/md5" 
    "crypto/rand" 
    "crypto/rsa" 
    "log" 
    ) 
var private_key *rsa.PrivateKey 
var public_key *rsa.PublicKey 
var encrypted,decrypted []byte 
func setUP(size int) bool{ 
    var err error 
    if private_key,err = rsa.GenerateKey(rand.Reader,size); err != nil { 
     log.Fatal(err) 
     return false 
    } 
    private_key.Precompute() 
    if err= private_key.Validate();err != nil { 
     log.Fatal(err) 
     return false 
    } 
    public_key = &private_key.PublicKey 
    return true 
} 
func encrypt(msg string) string { 
    var err error 
    var label []byte 
    md5h := md5.New() 
    if encrypted,err = rsa.EncryptOAEP(md5h,rand.Reader,public_key,[]byte(msg),label); err != nil { 
     log.Fatal(err) 
    } 
    return string(encrypted) 
} 
func decrypt(msg string) string { 
    var err error 
    var label []byte 
    md5h := md5.New() 
    if decrypted,err = rsa.DecryptOAEP(md5h,rand.Reader,private_key,[]byte(msg),label); err != nil { 
     log.Fatal(err) 
    } 
    return string(decrypted) 
} 

答えて

2

あなたは(あなたがあなたの例で示したように)別のGo 1に囲碁プログラムからデータを送信する場合、あなたはバイトとデシリアライズのスライスにencoding/gobhttps://golang.org/pkg/encoding/gob/をシリアル化するパッケージ(Encode)オブジェクトを使用することができます受け取ったバイトをGoオブジェクトに戻します(Decode)。ここでの例では(もhttps://play.golang.org/p/3bxbqGtqQY)です:に似

package main 

import (
    "bytes" 
    "crypto/rand" 
    "crypto/rsa" 
    "encoding/gob" 
    "fmt" 
    "log" 
) 

func main() { 
    priv, _ := rsa.GenerateKey(rand.Reader, 512) // skipped error checking for brevity 
    pub := priv.PublicKey 
    // adapted from https://golang.org/pkg/encoding/gob/#example__basic: 
    // Initialize the encoder and decoder. Normally enc and dec would be 
    // bound to network connections and the encoder and decoder would 
    // run in different processes. 
    var network bytes.Buffer  // Stand-in for a network connection 
    enc := gob.NewEncoder(&network) // Will write to network. 
    dec := gob.NewDecoder(&network) // Will read from network. 
    enc.Encode(&pub) 
    var pub2 = rsa.PublicKey{} 
    dec.Decode(&pub2) 
    if pub.N.Cmp(pub2.N) != 0 || pub.E != pub2.E { 
     log.Fatal("Public Keys at source and destination not equal") 
    } 
    fmt.Printf("OK - %#v\n", pub2) 
} 

出力:

OK -rsa.PublicKey{N:10881677056019504919833663670523712169444878787643568603135265932739968735275981472697621424678110007129031867528249518560683510901399549383480944574041391, E:65537}

はゴブブロブを送信すると、あなたはそれをたくさんやっている場合は特にJSONエンコーディングをやって、その後、より速く、より効率的にすることができますしかし、それがあなたにとって重要な要素であるかどうか、またデータ転送にテキスト(JSON)またはバイナリ形式(gobまたはprotobufs)を好むかどうかを判断する必要があります。

2

rsa.PublicKey[]byteにシリアライズする必要があります。これを行うには複数の方法がありますが、おそらくJSONを使用します。

構造体は次のようになります。構造体は、a)Publicおよびb)JSONでシリアライズ可能です。

type PublicKey struct { 
    N *big.Int // modulus 
    E int  // public exponent 
} 
関連する問題