Requirement is to have client server communication using RSA. I am not able to decrypt the message. Created private.pem and public.pem files using the generatekeys.go file.
Created 3 files server.go, client.go and generatekeys.go.
server.go -> This file add ‘n’ number of clients. The function recvAndEcho loads the private.pem file and decrypts the message using the private.pem file.
client.go -> This file loads the public.pem file and encrypts the message incoming from server.
**server.go**
package main
import (
"bufio"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"io"
"net"
"os"
"strings"
)
type server struct {
clients []io.Writer
}
func (s *server) addClient(c net.Conn) {
s.clients = append(s.clients, c)
}
func main() {
fmt.Println("Launching server...")
srv := &server{}
// listen on all interfaces
ln, _ := net.Listen("tcp", ":8081")
for {
// Listen for an incoming connection.
conn, err := ln.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
continue
}
srv.addClient(conn)
go srv.recvAndEcho(conn)
}
}
func (s *server) recvAndEcho(c io.ReadCloser) {
defer c.Close()
for {
netData, err := bufio.NewReader(c).ReadString('n')
if err != nil {
fmt.Println(err)
return
}
decryptedMessage, err := rsa.DecryptPKCS1v15(rand.Reader, getPrivateKey(), []byte(netData))
if err != nil {
fmt.Println("Error decrypting message:", err)
return
}
temp := strings.TrimSpace(string(decryptedMessage))
fmt.Println(temp)
s.broadcastMsg(netData)
}
}
func (s *server) broadcastMsg(msg string) {
for _, cl := range s.clients {
// Send the original msg back to the client
_, err := cl.Write([]byte(fmt.Sprintf("server replied: %sn", msg)))
if err != nil {
fmt.Println("server: failed to write!")
}
}
}
func loadPrivateKey(filename string) (*rsa.PrivateKey, error) {
data, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
block, _ := pem.Decode(data)
if block == nil || block.Type != "RSA PRIVATE KEY" {
return nil, errors.New("failed to decode PEM block containing private key")
}
return x509.ParsePKCS1PrivateKey(block.Bytes)
}
func getPrivateKey() *rsa.PrivateKey {
var err error
privateKey, err := loadPrivateKey("private.pem")
if err != nil {
fmt.Println("Error loading private key:", err)
os.Exit(1)
}
return privateKey
}
**client.go**
package main
import (
"bufio"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"log"
"net"
"os"
)
func main() {
// connect to this socket
conn, err := net.Dial("tcp", "127.0.0.1:8081")
if err != nil {
fmt.Println("Error accepting: ", err.Error())
}
go receive(conn)
sc := bufio.NewScanner(os.Stdin)
for sc.Scan() {
if sc.Err() != nil {
fmt.Println("scanner error!")
}
txt := sc.Text()
b := []byte(txt + "n")
_, err := conn.Write(b)
if err != nil {
fmt.Println("Failed to send data to the server!")
break
}
}
conn.Close()
}
func receive(c net.Conn) {
rd := bufio.NewReader(c)
var inbuf [64]byte
for {
n, err := rd.Read(inbuf[:])
encryptedMessage, err := rsa.EncryptPKCS1v15(rand.Reader, getPublicKey(), []byte(inbuf[:n]))
if err != nil {
fmt.Println("Error encrypting message:", err)
return
}
if err != nil {
fmt.Println("Failed to receive msg from the server!")
break
}
fmt.Print(encryptedMessage)
}
c.Close()
}
func loadPublicKey(filename string) (*rsa.PublicKey, error) {
data, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
block, _ := pem.Decode(data)
if block == nil || block.Type != "RSA PUBLIC KEY" {
return nil, errors.New("failed to decode PEM block containing public key")
}
pkey, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
panic(err)
}
rsaKey, ok := pkey.(*rsa.PublicKey)
if !ok {
log.Fatalf("got unexpected key type: %T", pkey)
}
return rsaKey, nil
}
func getPublicKey() *rsa.PublicKey {
var err error
publicKey, err := loadPublicKey("public.pem")
if err != nil {
fmt.Println("Error loading public key:", err)
os.Exit(1)
}
return publicKey
}
**generatekeys.go**
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"os"
)
func main() {
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
fmt.Println("Error generating private key:", err)
os.Exit(1)
}
publicKey := &privateKey.PublicKey
savePEMKey("private.pem", privateKey)
savePublicPEMKey("public.pem", publicKey)
}
func savePEMKey(filename string, key *rsa.PrivateKey) {
outFile, err := os.Create(filename)
if err != nil {
fmt.Println("Error creating file:", err)
os.Exit(1)
}
defer outFile.Close()
var privateKey = &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(key),
}
pem.Encode(outFile, privateKey)
}
func savePublicPEMKey(filename string, pubkey *rsa.PublicKey) {
pubASN1, err := x509.MarshalPKIXPublicKey(pubkey)
if err != nil {
fmt.Println("Error marshalling public key:", err)
os.Exit(1)
}
var pemkey = &pem.Block{
Type: "RSA PUBLIC KEY",
Bytes: pubASN1,
}
outFile, err := os.Create(filename)
if err != nil {
fmt.Println("Error creating file:", err)
os.Exit(1)
}
defer outFile.Close()
pem.Encode(outFile, pemkey)
}