2016-07-27 9 views
1

Ich habe versucht, eine einfache RSA-verschlüsselte Chat-App zu machen. Das Problem, auf das ich gestoßen bin, ist, dass ich den öffentlichen rsa-Schlüssel über die tcp-Verbindung senden muss, da net.Conn meines Wissens nur das type [] Byte akzeptiert.Wie ein rsa.PublicKey über eine TCP-Verbindung in gehen?

Problem Code

conn.Write([]byte(public_key)) 

Dies ist der Code, der meine complications.This Code der Funktion handle produziert unter. Ich verstehe, dass conn.Write nur das type [] Byte akzeptieren kann, aber es gibt irgendwo in der Umgebung. Wie kann ich den public_key an meinen Kunden übermitteln? Ich habe meinen gesamten Servercode für alle Fälle beigefügt. Auch, wenn Sie alle Server/Client-Code Kommentar erhalten möchten, und ich werde einen GitHub-Link erstellen. Thankyou

Nur für den Fall-Server-Code

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) 
} 

Antwort

2

Wenn Sie Daten von einem Go-Programm zu einem anderen gehen noch einem schicken (wie Sie in Ihren Beispielen zeigen), können Sie das Paket encoding/gobhttps://golang.org/pkg/encoding/gob/ verwenden serialisiert (Encode) ein Objekt in eine Scheibe von Bytes und deserialize (Decode) die empfangenen Bytes zurück in das Go-Objekt. Hier ist ein Beispiel (auch 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) 
} 

Ausgabe ähnlich:

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

Senden gob Blobs können schneller und effizienter dann tun JSON-Codierung vor allem, wenn Sie eine Menge tun es , aber Sie müssen entscheiden, ob dies für Sie von Bedeutung ist und ob Sie Text (JSON) oder Binärformat (Gob oder Protobufs) für den Datentransport bevorzugen.

2

Sie müssen die rsa.PublicKey zu einer []byte serialisieren. Es gibt mehrere Möglichkeiten, dies zu tun, aber ich würde wahrscheinlich mit JSON gehen.

Die Struktur sieht so aus, und alles in ihr ist a) Public und b) Serializable mit JSON.

type PublicKey struct { 
    N *big.Int // modulus 
    E int  // public exponent 
} 
Verwandte Themen