Created
May 29, 2016 21:13
-
-
Save a-h/ba32279974ce76c26e206905dc8e435e to your computer and use it in GitHub Desktop.
Sign and Verify Data With PEM Files
This file contains hidden or 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" | |
| "crypto/rand" | |
| "crypto/rsa" | |
| "crypto/sha256" | |
| "crypto/x509" | |
| "encoding/pem" | |
| "fmt" | |
| "io/ioutil" | |
| "log" | |
| ) | |
| func main() { | |
| // Create keys. | |
| pk := createPrivateKey() | |
| createPublicKey(pk) | |
| publicKey, err := loadPublicKey() | |
| // Create some data to sign. | |
| data := []byte("hello") | |
| fmt.Printf("Test data: %v\n", string(data)) | |
| // Generate a signature. | |
| signature, err := Sign(data, pk) | |
| if err != nil { | |
| log.Printf("Failed to sign data. %v", err) | |
| } | |
| fmt.Printf("Signature: %v\n", signature) | |
| // Verify the signature by rehashing it and passing it to the verify function. | |
| hash := sha256.Sum256(data) | |
| verification := Verify(publicKey, hash[:], signature) | |
| log.Printf("Verification result: %v\n", verification) | |
| // If the signature is modified, then the verification fails. | |
| verification = Verify(publicKey, hash[:], append(signature, 1)) | |
| log.Printf("Verification should have failed due to an invalid signature: %v\n", verification) | |
| // If the checksum doesn't match, then the verification fails. | |
| data = []byte("hello1") | |
| hash = sha256.Sum256(data) | |
| verification = Verify(publicKey, hash[:], signature) | |
| log.Printf("Verification should have failed due to a mismatched checksum and signature: %v\n", verification) | |
| } | |
| func createPrivateKey() (priv *rsa.PrivateKey) { | |
| privateKey, err := rsa.GenerateKey(rand.Reader, 1024) | |
| if err != nil { | |
| log.Printf("Failed to create private key, with err %v", err) | |
| } | |
| pem := pem.EncodeToMemory( | |
| &pem.Block{ | |
| Type: "RSA PRIVATE KEY", | |
| Bytes: x509.MarshalPKCS1PrivateKey(privateKey), | |
| }) | |
| ioutil.WriteFile("private.pem", pem, 0666) | |
| return privateKey | |
| } | |
| func createPublicKey(priv *rsa.PrivateKey) { | |
| der, err := x509.MarshalPKIXPublicKey(&priv.PublicKey) | |
| if err != nil { | |
| log.Print("Failed to marshal the public key.") | |
| } | |
| pem := pem.EncodeToMemory(&pem.Block{ | |
| Type: "RSA PUBLIC KEY", | |
| Bytes: der, | |
| }) | |
| ioutil.WriteFile("public.pem", pem, 0666) | |
| } | |
| // Sign data with a private key. | |
| func Sign(data []byte, priv *rsa.PrivateKey) (signature []byte, err error) { | |
| hashed := sha256.Sum256(data) | |
| hashSlice := hashed[:] | |
| return rsa.SignPKCS1v15(rand.Reader, priv, crypto.SHA256, hashSlice) | |
| } | |
| func loadPublicKey() (*rsa.PublicKey, error) { | |
| pemBytes, err := ioutil.ReadFile("public.pem") | |
| block, _ := pem.Decode(pemBytes) | |
| pub, err := x509.ParsePKIXPublicKey(block.Bytes) | |
| rsaPub, ok := pub.(*rsa.PublicKey) | |
| if !ok { | |
| log.Print("Failed to load the public key.") | |
| } | |
| return rsaPub, err | |
| } | |
| // Verify the hash. hashed is created by hashing the input message. The sig | |
| // parameter is the signature of the hash to verify. | |
| func Verify(pub *rsa.PublicKey, hashed []byte, sig []byte) error { | |
| return rsa.VerifyPKCS1v15(pub, crypto.SHA256, hashed, sig) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment