我一直在尝试制作一个简单的 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/