Created
June 8, 2023 06:38
-
-
Save TheAlchemistKE/31992846e73446a007dd75db5b1d9ec4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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