Skip to content

Instantly share code, notes, and snippets.

@chonlatee
Created June 25, 2019 08:48
Show Gist options
  • Save chonlatee/8e6db6ed5111984b93605302fbe599e4 to your computer and use it in GitHub Desktop.
Save chonlatee/8e6db6ed5111984b93605302fbe599e4 to your computer and use it in GitHub Desktop.
verify signature when you send signature to other machine ( eg. server to client )
package main
import (
"crypto/ecdsa"
"crypto/rand"
"crypto/sha256"
"crypto/x509"
"encoding/asn1"
"encoding/base64"
"encoding/pem"
"errors"
"fmt"
"log"
"math/big"
)
func main() {
privKey := []byte("-----BEGIN PRIVATE KEY-----\n" +
"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgHy8ZWd6zIyMDKWPK" +
"9DA5tDfpRo+f8TYEgjh88N3yHLOhRANCAASY6Wpd5GnpmWnslyNu9Y8cgQ01uJv3" +
"lhAgxC0THjuNOkTKbFeb8oxFqT3VxSNvv0zT8teoX8+CBisUzuZEzsST" +
"\n-----END PRIVATE KEY-----")
pubKey := []byte("-----BEGIN PUBLIC KEY-----\n" +
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmOlqXeRp6Zlp7JcjbvWPHIENNbib" +
"95YQIMQtEx47jTpEymxXm/KMRak91cUjb79M0/LXqF/PggYrFM7mRM7Ekw==" +
"\n-----END PUBLIC KEY-----")
privateKey, err := loadPrivateKey(privKey)
if err != nil {
panic(err)
}
publicKey, err := loadPublicKey(pubKey)
if err != nil {
panic(err)
}
msg := "hello, world"
hash := sha256.Sum256([]byte(msg))
b, err := privateKey.Sign(rand.Reader, hash[:], nil)
sig := base64.StdEncoding.EncodeToString(b)
/**
* in case you send signature to other machine like:
* {
* message: "hello, world",
* signature: sig
* }
**/
der, err := base64.StdEncoding.DecodeString(sig)
if err != nil {
log.Fatal("decode base64 error")
}
type ECDSASignature struct {
R, S *big.Int
}
ecdsaSig := &ECDSASignature{}
_, err = asn1.Unmarshal(der, ecdsaSig)
if err != nil {
log.Fatal("unmarshal ecdsa error")
}
valid := ecdsa.Verify(publicKey, hash[:], ecdsaSig.R, ecdsaSig.S)
fmt.Println("verify signature:", valid)
}
func loadPrivateKey(privateKey []byte) (*ecdsa.PrivateKey, error) {
block, _ := pem.Decode(privateKey)
if block == nil || block.Type != "PRIVATE KEY" {
log.Fatal("failed to decode PEM block containing private key")
return nil, errors.New("Failed to decode PEM private key")
}
priv, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return nil, errors.New("Failed to parse ECDSA private key")
}
switch priv := priv.(type) {
case *ecdsa.PrivateKey:
return priv, nil
}
return nil, errors.New("Unsupported private key type")
}
func loadPublicKey(publicKey []byte) (*ecdsa.PublicKey, error) {
block, _ := pem.Decode([]byte(publicKey))
if block == nil || block.Type != "PUBLIC KEY" {
return nil, errors.New("Failed to decode PEM public key")
}
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, errors.New("Failed to parse ECDSA public key")
}
switch pub := pub.(type) {
case *ecdsa.PublicKey:
return pub, nil
}
return nil, errors.New("Unsupported public key type")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment