encryption - 如何在go中通过tcp连接发送rsa.PublicKey?

标签 encryption go tcp rsa

我一直在尝试制作一个简单的 RSA 加密聊天应用程序。我遇到的问题是必须通过 tcp 连接发送 rsa 公钥,如 net.Conn ,据我所知仅接受 []byte 类型。

问题代码

 conn.Write([]byte(public_key))

这是导致我的复杂情况的代码。该代码位于函数handleRequest 下。我知道 conn.Write 只能接受 []byte 类型,但是有没有什么地方可以解决这个问题。如何将 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)
            }
        }
    }
}

加密.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)
}

最佳答案

如果您要将数据从一个 Go 程序发送到另一个 Go 程序(如示例中所示),您可以使用包 encoding/gob https://golang.org/pkg/encoding/gob/将对象序列化(Encode)为字节 slice ,并将接收到的字节反序列化(Decode)回 Go 对象。这是一个示例(也是 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)
}

输出类似于:

确定 -rsa.PublicKey{N:10881677056019504919833663670523712169444878787643568603135265932739968735275981472697621424678110007129 031867528249518560683510901399549383480944574041391,E:65537}

发送 gob blob 比进行 JSON 编码更快、更高效,尤其是在您进行大量编码的情况下,但您需要确定这对您来说是否是一个重要因素以及您是否喜欢文本 (JSON) 还是二进制格式(gob 或 protobuf)用于数据传输。

关于encryption - 如何在go中通过tcp连接发送rsa.PublicKey?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38612279/

相关文章:

linux - 如何判断附加到 Azure 虚拟机的磁盘是否已加密?

sql - Postgres无限 self 加入

go - Golang简化折线数据

c - 错误: Invalid argument while trying to accept a connection from a client

c - 使用 C 语言套接字编程的简单 HTTP 服务器在 Chrome 上失败

c# - 端口DDI登录密码加密到Metro

security - HTTPS header 是否加密?

post - 如何确定TCP/IP中上传+下载的总数据量

javascript - 解密 Javascript

go - 卡夫卡消费者 : How to programatically consume from specific offset in Go Sarama