Skip to content

Instantly share code, notes, and snippets.

@TheAlchemistKE
Created June 8, 2023 06:38
Show Gist options
  • Save TheAlchemistKE/31992846e73446a007dd75db5b1d9ec4 to your computer and use it in GitHub Desktop.
Save TheAlchemistKE/31992846e73446a007dd75db5b1d9ec4 to your computer and use it in GitHub Desktop.
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"io"
"os"
)
func generateRSAKeyPair() (*rsa.PrivateKey, error) {
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return nil, err
}
return privateKey, nil
}
func savePrivateKeyToPEM(privateKey *rsa.PrivateKey, filename string) error {
pemBlock := &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
}
file, err := openFile(filename)
if err != nil {
return err
}
defer file.Close()
if err := pem.Encode(file, pemBlock); err != nil {
return err
}
return nil
}
func loadPrivateKeyFromPEM(filename string) (*rsa.PrivateKey, error) {
file, err := openFile(filename)
if err != nil {
return nil, err
}
defer file.Close()
pemBytes, err := io.ReadAll(file)
if err != nil {
return nil, err
}
block, _ := pem.Decode(pemBytes)
privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
return privateKey, nil
}
func savePublicKeyToPEM(publicKey *rsa.PublicKey, filename string) error {
pemBytes, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
return err
}
pemBlock := &pem.Block{
Type: "PUBLIC KEY",
Bytes: pemBytes,
}
file, err := openFile(filename)
if err != nil {
return err
}
defer file.Close()
if err := pem.Encode(file, pemBlock); err != nil {
return err
}
return nil
}
func loadPublicKeyFromPEM(filename string) (*rsa.PublicKey, error) {
file, err := openFile(filename)
if err != nil {
return nil, err
}
defer file.Close()
pemBytes, err := io.ReadAll(file)
if err != nil {
return nil, err
}
block, _ := pem.Decode(pemBytes)
publicKey, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
return publicKey.(*rsa.PublicKey), nil
}
func encrypt(publicKey *rsa.PublicKey, plaintext []byte) ([]byte, error) {
ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, plaintext)
if err != nil {
return nil, err
}
return ciphertext, nil
}
func decrypt(privateKey *rsa.PrivateKey, ciphertext []byte) ([]byte, error) {
plaintext, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, ciphertext)
if err != nil {
return nil, err
}
return plaintext, nil
}
func openFile(filename string) (*os.File, error) {
file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, 0600)
if err != nil {
return nil, err
}
return file, nil
}
func main() {
// Generate RSA key pair
privateKey, err := generateRSAKeyPair()
if err != nil {
fmt.Println("Key generation error:", err)
return
}
// Save private key to PEM file
err = savePrivateKeyToPEM(privateKey, "private.pem")
if err != nil {
fmt.Println("Private key saving error:", err)
return
}
// Load private key from PEM file
privateKey, err = loadPrivateKeyFromPEM("private.pem")
if err != nil {
fmt.Println("Private key loading error:", err)
return
}
// Get the public key from the private key
publicKey := privateKey.Public().(*rsa.PublicKey)
// Save public key to PEM file
err = savePublicKeyToPEM(publicKey, "public.pem")
if err != nil {
fmt.Println("Public key saving error:", err)
return
}
// Load public key from PEM file
publicKey, err = loadPublicKeyFromPEM("public.pem")
if err != nil {
fmt.Println("Public key loading error:", err)
return
}
// Encrypt using the public key
plaintext := []byte("Hello, world!")
ciphertext, err := encrypt(publicKey, plaintext)
if err != nil {
fmt.Println("Encryption error:", err)
return
}
fmt.Println("Encrypted text:", string(ciphertext))
// Decrypt using the private key
decryptedPlaintext, err := decrypt(privateKey, ciphertext)
if err != nil {
fmt.Println("Decryption error:", err)
return
}
fmt.Println("Decrypted plaintext:", string(decryptedPlaintext))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment