Golang : Generate DSA private, public key and PEM files example




For this tutorial, we will build on the previous tutorial on how to save private and public key files to learn how to generate DSA private, public key and PEM files.

Executing the code below will generate 3 files and output the DSA related data to screen.

 package main

 import (
 "crypto/dsa"
 "crypto/md5"
 "crypto/rand"
 "encoding/asn1"
 "encoding/gob"
 "encoding/pem"
 "fmt"
 "hash"
 "io"
 "math/big"
 "os"
 )

 func main() {

 params := new(dsa.Parameters)

 // see http://golang.org/pkg/crypto/dsa/#ParameterSizes
 if err := dsa.GenerateParameters(params, rand.Reader, dsa.L1024N160); err != nil {
 fmt.Println(err)
 os.Exit(1)
 }

 privatekey := new(dsa.PrivateKey)
 privatekey.PublicKey.Parameters = *params
 dsa.GenerateKey(privatekey, rand.Reader) // this generates a public & private key pair

 var pubkey dsa.PublicKey
 pubkey = privatekey.PublicKey

 fmt.Println("Private Key :")
 fmt.Printf("%x \n", privatekey)

 fmt.Println("Public Key :")
 fmt.Printf("%x \n", pubkey)

 // save private and public key separately
 privatekeyfile, err := os.Create("DSAprivate.key")
 if err != nil {
 fmt.Println(err)
 os.Exit(1)
 }
 privatekeyencoder := gob.NewEncoder(privatekeyfile)
 privatekeyencoder.Encode(privatekey)
 privatekeyfile.Close()

 publickeyfile, err := os.Create("DSApublic.key")
 if err != nil {
 fmt.Println(err)
 os.Exit(1)
 }

 publickeyencoder := gob.NewEncoder(publickeyfile)
 publickeyencoder.Encode(pubkey)
 publickeyfile.Close()

 // save DSA public key to PEM encoded file
 pemfile, err := os.Create("DSApublickey.pem")

 if err != nil {
 fmt.Println(err)
 os.Exit(1)
 }

 // http://golang.org/pkg/encoding/pem/#Block
 // The decoded bytes of the contents. Typically a DER encoded ASN.1 structure.

 asn1Bytes, err := asn1.Marshal(pubkey)

 if err != nil {
 fmt.Println(err)
 os.Exit(1)
 }

 var pemkey = &pem.Block{
 Type:  "PUBLIC KEY",
 Bytes: asn1Bytes}

 err = pem.Encode(pemfile, pemkey)

 if err != nil {
 fmt.Println(err)
 os.Exit(1)
 }

 pemfile.Close()

 // ------------------------------
 // below here is bonus

 // Sign
 var h hash.Hash
 h = md5.New()
 r := big.NewInt(0)
 s := big.NewInt(0)

 io.WriteString(h, "This is the message to be signed and verified!")
 signhash := h.Sum(nil)

 r, s, err = dsa.Sign(rand.Reader, privatekey, signhash)
 if err != nil {
 fmt.Println(err)
 }

 signature := r.Bytes()
 signature = append(signature, s.Bytes()...)

 fmt.Printf("Signature : %x\n", signature)

 // Verify
 verifystatus := dsa.Verify(&pubkey, signhash, r, s)
 fmt.Println(verifystatus) // should be true

 // we add additional data to change the signhash
 io.WriteString(h, "This message is NOT to be signed and verified!")
 signhash = h.Sum(nil)

 verifystatus = dsa.Verify(&pubkey, signhash, r, s)
 fmt.Println(verifystatus) // should be false
 }

output of PEM file:

 -----BEGIN PUBLIC KEY-----
 MIIBpjCCAR4CgYEA1cKOQUxDRqRHt8yR5vfEunyFB6pblE9W/fyaJHgpWMzkvSHX
 mZvDhN5huH3OM0vC5Y8UbfyplET3x/HfXUbDUgk4bT0CrWHmrANMjdPgStZF+nWP
 Yfa6QUyVbRZumI6iBaCH63107scE8tygmwSW3n1jYLoSv6VItDEiBIdoK18CFQC6
 q4LlyX4YZblOKYw8CFyPShtcAwKBgHAN+TWyUhqCVZmwUdH3pJelT4iT9vkg4NLn
 1h+qJJ1XU+OILAAeuO3z8vLMIpeFaDL5CvUb7S0vSqx2EFj/G67aH9nL0MwtXjn7
 SCy4EOF5dlHbafXj4PnPrvo3/Mr+3a2i5lenlhyyb1Vnd/0VcrGwWleAfDBuGdYu
 S5WCYAj3AoGBAMDl+N8XI3LBi/LUQbi9di0tvA/2t+c6UZTT/CDTkyDucFNEeqWI
 sdOsf+hIbI8pEy81y6yBc50wcf1uqcZxovKsZbuv8vS3NBPaeOT7l6ltYdNxzg/7
 QFfi3qQXXLONWYXW4diWaZu6Kq5XvhfWkoUdGzGiD84UVW7jmeDy/Px6
 -----END PUBLIC KEY-----

References :

https://www.socketloop.com/tutorials/golang-example-for-dsa-functions

https://www.socketloop.com/tutorials/golang-saving-private-and-public-key-to-files

  See also : Golang : Example for DSA(Digital Signature Algorithm) package functions





By Adam Ng

IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.


Advertisement