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 :
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
Tutorials
+14.2k Golang : Overwrite previous output with count down timer
+4.8k Golang : Constant and variable names in native language
+20.6k Golang : How to force compile or remove object files first before rebuild?
+11.3k Get form post value in Go
+18.4k Golang : Padding data for encryption and un-padding data for decryption
+11.7k Golang : Detect user location with HTML5 geo-location
+6.7k Golang : Calculate BMI and risk category
+9.4k Javascript : Read/parse JSON data from HTTP response
+9.8k Golang : Edge detection with Sobel method
+21.9k Golang : Repeat a character by multiple of x factor
+36.2k Golang : Display float in 2 decimal points and rounding up or down
+12.3k Golang : Get absolute path to binary for os.Exec function with exec.LookPath