Hey there, crypto wizard! Ready to see some real-world magic with Go's crypto package? We've learned all these cool crypto spells, now let's put them to use in some practical enchantments! We'll create two powerful artifacts: a secure file encryption spell and a Public Key Infrastructure (PKI) summoning ritual.
Enchantment #1: The Secure File Encryption Spell
Let's create a magical scroll that can securely encrypt and decrypt files using the mighty AES-GCM (Galois/Counter Mode) enchantment. This spell provides both secrecy and integrity protection!
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"errors"
"fmt"
"io"
"os"
)
// Our encryption spell
func encrypt(plaintext []byte, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
nonce := make([]byte, gcm.NonceSize())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return nil, err
}
return gcm.Seal(nonce, nonce, plaintext, nil), nil
}
// Our decryption counter-spell
func decrypt(ciphertext []byte, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
if len(ciphertext) < gcm.NonceSize() {
return nil, errors.New("ciphertext too short")
}
nonce, ciphertext := ciphertext[:gcm.NonceSize()], ciphertext[gcm.NonceSize():]
return gcm.Open(nil, nonce, ciphertext, nil)
}
// Enchant a file with our encryption spell
func encryptFile(inputFile, outputFile string, key []byte) error {
plaintext, err := os.ReadFile(inputFile)
if err != nil {
return err
}
ciphertext, err := encrypt(plaintext, key)
if err != nil {
return err
}
return os.WriteFile(outputFile, ciphertext, 0644)
}
// Remove the encryption enchantment from a file
func decryptFile(inputFile, outputFile string, key []byte) error {
ciphertext, err := os.ReadFile(inputFile)
if err != nil {
return err
}
plaintext, err := decrypt(ciphertext, key)
if err != nil {
return err
}
return os.WriteFile(outputFile, plaintext, 0644)
}
func main() {
// Summon a magical key
key := make([]byte, 32) // AES-256
if _, err := rand.Read(key); err != nil {
panic("Our magical key summoning failed!")
}
// Cast our encryption spell
err := encryptFile("secret_scroll.txt", "encrypted_scroll.bin", key)
if err != nil {
panic("Our encryption spell fizzled!")
}
fmt.Println("Scroll successfully enchanted with secrecy!")
// Remove the encryption enchantment
err = decryptFile("encrypted_scroll.bin", "decrypted_scroll.txt", key)
if err != nil {
panic("Our decryption counter-spell backfired!")
}
fmt.Println("Scroll successfully disenchanted!")
}
This magical scroll demonstrates secure file encryption using AES-GCM. It includes protection against magical mishaps (error handling), secure summoning of random numbers for the nonce, and proper magical key management practices.
Enchantment #2: The PKI Summoning Ritual
Now, let's perform a more complex ritual to summon a basic Public Key Infrastructure (PKI) system. This system can generate magical certificates, sign them with a Certificate Authority (CA), and verify these mystical documents.
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"math/big"
"os"
"time"
)
// Summon a magical key pair
func generateKey() (*ecdsa.PrivateKey, error) {
return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
}
// Create a mystical certificate
func createCertificate(template, parent *x509.Certificate, pub interface{}, priv interface{}) (*x509.Certificate, []byte, error) {
certDER, err := x509.CreateCertificate(rand.Reader, template, parent, pub, priv)
if err != nil {
return nil, nil, err
}
cert, err := x509.ParseCertificate(certDER)
if err != nil {
return nil, nil, err
}
return cert, certDER, nil
}
// Summon a Certificate Authority
func generateCA() (*x509.Certificate, *ecdsa.PrivateKey, error) {
caPrivKey, err := generateKey()
if err != nil {
return nil, nil, err
}
template := x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{
Organization: []string{"Wizards' Council"},
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(10, 0, 0),
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
IsCA: true,
}
caCert, _, err := createCertificate(&template, &template, &caPrivKey.PublicKey, caPrivKey)
if err != nil {
return nil, nil, err
}
return caCert, caPrivKey, nil
}
// Generate a certificate for a magical domain
func generateCertificate(caCert *x509.Certificate, caPrivKey *ecdsa.PrivateKey, domain string) (*x509.Certificate, *ecdsa.PrivateKey, error) {
certPrivKey, err := generateKey()
if err != nil {
return nil, nil, err
}
template := x509.Certificate{
SerialNumber: big.NewInt(2),
Subject: pkix.Name{
Organization: []string{"Wizards' Guild"},
CommonName: domain,
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(1, 0, 0),
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
DNSNames: []string{domain},
}
cert, _, err := createCertificate(&template, caCert, &certPrivKey.PublicKey, caPrivKey)
if err != nil {
return nil, nil, err
}
return cert, certPrivKey, nil
}
// Inscribe a certificate onto a magical parchment (PEM)
func saveCertificateToPEM(cert *x509.Certificate, filename string) error {
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw})
return os.WriteFile(filename, certPEM, 0644)
}
// Inscribe a private key onto a magical parchment (PEM)
func savePrivateKeyToPEM(privKey *ecdsa.PrivateKey, filename string) error {
privKeyBytes, err := x509.MarshalECPrivateKey(privKey)
if err != nil {
return err
}
privKeyPEM := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: privKeyBytes})
return os.WriteFile(filename, privKeyPEM, 0600)
}
func main() {
// Summon the Certificate Authority
caCert, caPrivKey, err := generateCA()
if err != nil {
panic("The CA summoning ritual failed!")
}
// Inscribe the CA certificate and private key
err = saveCertificateToPEM(caCert, "ca_cert.pem")
if err != nil {
panic("Failed to inscribe the CA certificate!")
}
err = savePrivateKeyToPEM(caPrivKey, "ca_key.pem")
if err != nil {
panic("Failed to inscribe the CA private key!")
}
// Generate a certificate for a magical domain
domain := "hogwarts.edu"
cert, privKey, err := generateCertificate(caCert, caPrivKey, domain)
if err != nil {
panic("The domain certificate summoning failed!")
}
// Inscribe the domain certificate and private key
err = saveCertificateToPEM(cert, "domain_cert.pem")
if err != nil {
panic("Failed to inscribe the domain certificate!")
}
err = savePrivateKeyToPEM(privKey, "domain_key.pem")
if err != nil {
panic("Failed to inscribe the domain private key!")
}
fmt.Println("The PKI summoning ritual was successful! CA and domain certificates have been manifested.")
}
This mystical ritual demonstrates the creation of a simple PKI system, including:
- Summoning a Certificate Authority (CA)
- Using the CA to bless a domain certificate with its magical signature
- Inscribing certificates and private keys onto magical parchments (PEM format)
These examples showcase real-world applications of Go's crypto package, demonstrating secure file encryption and a basic PKI system. They incorporate many of the best practices and concepts we've discussed, such as proper key management, secure random number generation, and the use of modern cryptographic algorithms.
Remember, young wizard, when implementing these cryptographic systems in the real world, always ensure that your spells are thoroughly reviewed and tested by other master wizards. And for the most critical magical components, consider using established grimoires (libraries) when possible.
Now go forth and cast your crypto spells responsibly! May your secrets remain secret and your identities remain verified!
Top comments (0)