How to Sign and Verify Data in Go

Sign and verify data in Go using crypto/rsa or crypto/ecdsa packages with SHA256 hashing for secure digital signatures.

Use the crypto standard library packages to sign and verify data with asymmetric keys. The crypto/rsa package handles signing and verification using RSA keys, while crypto/ecdsa does the same for elliptic curve keys. Here is a minimal example using RSA:

package main

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/pem"
	"fmt"
)

func main() {
	// Generate a private key
	priv, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		panic(err)
	}

	// Data to sign
	data := []byte("Hello, World!")
	h := sha256.Sum256(data)

	// Sign the hash
	signature, err := rsa.SignPKCS1v15(rand.Reader, priv, crypto.SHA256, h[:])
	if err != nil {
		panic(err)
	}

	// Extract public key
	pub := &priv.PublicKey

	// Verify the signature
	err = rsa.VerifyPKCS1v15(pub, crypto.SHA256, h[:], signature)
	if err != nil {
		fmt.Println("Verification failed:", err)
	} else {
		fmt.Println("Signature verified successfully")
	}

	// Encode private key to PEM for storage
	privBytes := x509.MarshalPKCS1PrivateKey(priv)
	privPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: privBytes})
	fmt.Println(string(privPEM))

	// Encode public key to PEM
	pubBytes, _ := x509.MarshalPKIXPublicKey(pub)
	pubPEM := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: pubBytes})
	fmt.Println(string(pubPEM))
}

Replace crypto/rsa with crypto/ecdsa and adjust functions accordingly for elliptic curve cryptography.