Golang : Example for RSA package functions




One of the most practicable and popular cryptography systems is the RSA. The encryption works by allowing the public/encryption key to be ... well publicly available while the private/decryption key to be kept private. You can see RSA commonly used in email and secure shell login.

RSA stands for Ron Rivest, Adi Shamir and Leonard Adleman, who first publicly described the algorithm in 1977.

In this example, we will show you how to use each of the functions listed in the crypto/rsa package.

 package main

 import (
 "crypto"
 "crypto/md5"
 "crypto/rand"
 "crypto/rsa"
 "fmt"
 "io"
 "os"
 )

 func main() {

 // generate private key
 privatekey, err := rsa.GenerateKey(rand.Reader, 1024)

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

 D := privatekey.D //private exponent
 Primes := privatekey.Primes
 PCValues := privatekey.Precomputed

 // Note : Only used for 3rd and subsequent primes
 //CRTVal := privatekey.Precomputed.CRTValues

 fmt.Println("Private Key : ", privatekey)
 fmt.Println()
 fmt.Println("Private Exponent : ", D.String())
 fmt.Println()
 fmt.Printf("Primes : %s %s \n", Primes[0].String(), Primes[1].String())
 fmt.Println()
 fmt.Printf("Precomputed Values : Dp[%s] Dq[%s]\n", PCValues.Dp.String(), PCValues.Dq.String())
 fmt.Println()
 fmt.Printf("Precomputed Values : Qinv[%s]", PCValues.Qinv.String())
 fmt.Println()

 // Note : Only used for 3rd and subsequent primes
 //fmt.Printf("CRTValues : Exp[%s]\n Coeff[%s]\n R[%s]\n", CRTVal[2].Exp.String(), CRTVal[2].Coeff.String(), CRTVal[2].R.String())

 // Note : if you want to have multi primes,
 // use rsa.GenerateMultiPrimeKey() function instead of
 // rsa.GenerateKey() function
 // see http://golang.org/pkg/crypto/rsa/#GenerateMultiPrimeKey

 // http://golang.org/pkg/crypto/rsa/#PrivateKey.Precompute
 privatekey.Precompute()

 // http://golang.org/pkg/crypto/rsa/#PrivateKey.Validate
 err = privatekey.Validate()

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

 var publickey *rsa.PublicKey
 publickey = &privatekey.PublicKey
 N := publickey.N // modulus
 E := publickey.E // public exponent

 fmt.Println("Public key ", publickey)
 fmt.Println()
 fmt.Println("Public Exponent : ", E)
 fmt.Println()
 fmt.Println("Modulus : ", N.String())
 fmt.Println()

 // EncryptOAEP
 msg := []byte("The secret message!")
 label := []byte("")
 md5hash := md5.New()

 encryptedmsg, err := rsa.EncryptOAEP(md5hash, rand.Reader, publickey, msg, label)

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

 fmt.Printf("OAEP encrypted [%s] to \n[%x]\n", string(msg), encryptedmsg)
 fmt.Println()

 // DecryptOAEP
 decryptedmsg, err := rsa.DecryptOAEP(md5hash, rand.Reader, privatekey, encryptedmsg, label)

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

 fmt.Printf("OAEP decrypted [%x] to \n[%s]\n", encryptedmsg, decryptedmsg)
 fmt.Println()

 // EncryptPKCS1v15
 encryptedPKCS1v15, errPKCS1v15 := rsa.EncryptPKCS1v15(rand.Reader, publickey, msg)

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

 fmt.Printf("PKCS1v15 encrypted [%s] to \n[%x]\n", string(msg), encryptedPKCS1v15)
 fmt.Println()

 // DecryptPKCS1v15
 decryptedPKCS1v15, err := rsa.DecryptPKCS1v15(rand.Reader, privatekey, encryptedPKCS1v15)

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

 fmt.Printf("PKCS1v15 decrypted [%x] to \n[%s]\n", encryptedPKCS1v15, decryptedPKCS1v15)
 fmt.Println()

 // SignPKCS1v15
 var h crypto.Hash
 message := []byte("This is the message to be signed!")
 hash := md5.New()
 io.WriteString(hash, string(message))
 hashed := hash.Sum(nil)

 signature, err := rsa.SignPKCS1v15(rand.Reader, privatekey, h, hashed)

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

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

 //VerifyPKCS1v15
 err = rsa.VerifyPKCS1v15(publickey, h, hashed, signature)

 if err != nil {
 fmt.Println("VerifyPKCS1v15 failed")
 os.Exit(1)
 } else {
 fmt.Println("VerifyPKCS1v15 successful")
 }
 fmt.Println()

 // SignPSS
 var opts rsa.PSSOptions
 opts.SaltLength = rsa.PSSSaltLengthAuto // for simple example

 PSSmessage := []byte("Message to be PSSed!")
 newhash := crypto.MD5
 pssh := newhash.New()
 pssh.Write(PSSmessage)
 hashed = pssh.Sum(nil)

 signaturePSS, err := rsa.SignPSS(rand.Reader, privatekey, newhash, hashed, &opts)

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

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

 //VerifyPSS
 err = rsa.VerifyPSS(publickey, newhash, hashed, signaturePSS, &opts)

 if err != nil {
 fmt.Println("VerifyPSS failed")
 os.Exit(1)
 } else {
 fmt.Println("VerifyPSS successful")
 }

 }

Sample output :

go run rsa.go

Private Key : &{{14069868.....1134595521000335073 []}}

Private Exponent : 5992956235453428....7114123469729744785553

Primes : 1068234819....6154480540983

Precomputed Values : Dp[394485849....817550064792145] Dq[7908872...711190209031]

Precomputed Values : Qinv[10207476873..0335073]

Public key &{1406986827....23117039 65537}

Public Exponent : 65537

Modulus : 140698682716428....100805145523117039

OAEP encrypted [The secret message!] to [97052db00....05dffbe51]

OAEP decrypted [97052db0010.....605dffbe51] to [The secret message!]

PKCS1v15 encrypted [The secret message!] to [c029be25bd15a1bfa6.....c3cb617f92fd94]

PKCS1v15 decrypted [c029be25bd15a...b617f92fd94] to [The secret message!]

PKCS1v15 Signature : 53968867c6b26f3...de16194fb5e VerifyPKCS1v15 successful

PSS Signature : 8a49cb40a22....dc8ed91acd12aa VerifyPSS successful

The simplicity of this example is for easier understanding on how to use the functions. For more advanced implementation of these functions, please see https://code.google.com/p/go/source/browse/src/pkg/crypto/rsa/

Reference :

http://golang.org/pkg/crypto/rsa/





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