RSA Key

  1. Create a rsa.go file and add the contents as shown below.

rsa.go

package main  
import (  
 "bytes"  
 "encoding/base64"  
 "crypto/sha256"  
 "encoding/binary"  
 "fmt"  
 "log"  
 "github.com/miekg/pkcs11"  
)  
const (  
 pin = "87654321"  
)  
var ()  
func main() {  
 // Init PKCS11  
 p := pkcs11.New("/opt/utimaco/lib/libcs_pkcs11_R3.so")  
 err := p.Initialize()  
 if err != nil {  
 panic(err)  
 }  
 defer p.Destroy()  
 defer p.Finalize()  
 slots, err := p.GetSlotList(true)  
 if err != nil {  
 panic(err)  
 }  
 session, err := p.OpenSession(slots[0],   
pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)  
 if err != nil {
 panic(err)  
 }  
 defer p.CloseSession(session)  
 err = p.Login(session, pkcs11.CKU_USER, pin)  
 if err != nil {  
 panic(err)  
 }  
 defer p.Logout(session)  
 info, err := p.GetInfo()  
 if err != nil {  
 panic(err)  
 }  
 fmt.Printf("CryptokiVersion.Major %v", info.CryptokiVersion.Major)  
 fmt.Println()  
 buf := new(bytes.Buffer)  
 buf = new(bytes.Buffer)  
 var num uint16 = 1  
 num = 1  
 err = binary.Write(buf, binary.LittleEndian, num)  
 if err != nil {  
 log.Fatalf("binary.Write failed: %v", err)  
 }  
 pubID := buf.Bytes()  
 buf = new(bytes.Buffer)  
 num = 2  
 err = binary.Write(buf, binary.LittleEndian, num)  
 if err != nil {  
 log.Fatalf("binary.Write failed: %v", err)  
 }  
 privID := buf.Bytes()  
 publicKeyTemplate := []*pkcs11.Attribute{  
 pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY),  
 pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_RSA),  
 pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),  
 pkcs11.NewAttribute(pkcs11.CKA_VERIFY, true),  
 pkcs11.NewAttribute(pkcs11.CKA_ENCRYPT, true),  
 pkcs11.NewAttribute(pkcs11.CKA_WRAP, true),
 pkcs11.NewAttribute(pkcs11.CKA_MODULUS_BITS, 2048),  
 pkcs11.NewAttribute(pkcs11.CKA_LABEL, "pub1"),  
 pkcs11.NewAttribute(pkcs11.CKA_ID, pubID),  
 }  
 privateKeyTemplate := []*pkcs11.Attribute{  
 pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PRIVATE_KEY),  
 pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_RSA),  
 pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),  
 pkcs11.NewAttribute(pkcs11.CKA_SIGN, true),  
 pkcs11.NewAttribute(pkcs11.CKA_DECRYPT, true),  
 pkcs11.NewAttribute(pkcs11.CKA_LABEL, "priv1"),  
 pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, true),  
 pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, true),  
 pkcs11.NewAttribute(pkcs11.CKA_WRAP_WITH_TRUSTED, false),  
 pkcs11.NewAttribute(pkcs11.CKA_UNWRAP, true),  
 pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, true),  
 pkcs11.NewAttribute(pkcs11.CKA_ID, privID),  
 }  
 pbk, pvk, err := p.GenerateKeyPair(session,  
   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS_KEY_PAIR_GEN,   
nil)},  
 publicKeyTemplate, privateKeyTemplate)  
 var (  
 // OAEPLabel defines the label we use for OAEP encryption; this cannot   
be changed  
 OAEPLabel = []byte("")  
 // OAEPSha256Params describes the OAEP parameters with sha256 hash   
algorithm  
 OAEPSha256Params = &pkcs11.OAEPParams{  
 HashAlg: pkcs11.CKM_SHA256,  
 MGF: pkcs11.CKG_MGF1_SHA256,  
 SourceType: pkcs11.CKZ_DATA_SPECIFIED,  
 SourceData: OAEPLabel,  
 }  
)  
 // Encryption  
 err = p.EncryptInit(session,   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS_OAEP,   
OAEPSha256Params)}, pbk )  
 if err != nil {
 panic(fmt.Sprintf("EncryptInit() failed %s\n", err))  
 }  
 ct, err := p.Encrypt(session, []byte("fooooooo"))  
 if err != nil {  
 panic(fmt.Sprintf("Encrypt() failed %s\n", err))  
 }  
 // Decryption  
 err = p.DecryptInit(session,   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS_OAEP,   
OAEPSha256Params)}, pvk)  
 plaintext, err := p.Decrypt(session, ct)  
 _ = plaintext  
 _ = err  
 // Signing  
 msg := []byte("foo")  
 fmt.Printf("Signing %d bytes with %s\n", len(msg), msg)  
 err = p.SignInit(session,   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_SHA256_RSA_PKCS, nil)},   
pvk)  
 if err != nil {  
 log.Fatalf("Signing Initiation failed (%s)\n", err.Error())  
 }  
 sig, err := p.Sign(session, msg)  
 if err != nil {  
 err = fmt.Errorf("Signing failed (%s)\n", err.Error())  
 return  
 }  
 log.Printf("Signature %s", base64.RawStdEncoding.EncodeToString(sig))  
 // Verification  
 digest := sha256.Sum256(msg)  
 err = p.VerifyInit(session,   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_SHA256_RSA_PKCS, nil)},   
pbk)  
 err = p.Verify(session, digest[:], sig)  
 log.Printf(">>>>>> Signature Verified")  
 id := buf.Bytes()
 //Create AES key which is enabled for wrapping  
 aesKeyTemplate := []*pkcs11.Attribute{  
 pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_SECRET_KEY),  
 pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_AES),  
 pkcs11.NewAttribute(pkcs11.CKA_ENCRYPT, true),  
 pkcs11.NewAttribute(pkcs11.CKA_DECRYPT, true),  
 pkcs11.NewAttribute(pkcs11.CKA_WRAP, true),  
 pkcs11.NewAttribute(pkcs11.CKA_UNWRAP, true),  
 pkcs11.NewAttribute(pkcs11.CKA_VERIFY, false),  
 pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),  
 pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, true),  
 pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, true), // we don't   
need to extract this..  
 pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, true),  
 pkcs11.NewAttribute(pkcs11.CKA_VALUE_LEN, 32),  
 pkcs11.NewAttribute(pkcs11.CKA_LABEL, "WrappingAESKey"), /*   
Name of Key */  
 pkcs11.NewAttribute(pkcs11.CKA_ID, id),  
 }  
 importedPrivID := buf.Bytes()  
 aesKeyTemplate2 := []*pkcs11.Attribute{  
 pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_SECRET_KEY),  
 pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_AES),  
 pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),  
 pkcs11.NewAttribute(pkcs11.CKA_LABEL, "UnwrappedAESKey"), /*   
Name of Key */  
 pkcs11.NewAttribute(pkcs11.CKA_ID, importedPrivID),  
 }  
aesKey, err := p.GenerateKey(session,  
 []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_AES_KEY_GEN   
, nil)},  
 aesKeyTemplate)  
 log.Printf("Created AES Key: %v", aesKey)  
{  
 // Wrapping  
wrappedPrivBytes, err := p.WrapKey(session,   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS, nil)}, pbk,   
aesKey)  
 // Unwrapping 
 ik, err := p.UnwrapKey(session,   
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS, nil)}, pvk,   
wrappedPrivBytes, aesKeyTemplate2)  
 _ = ik  
 _ = err  
}  
}  

Update Slot PIN and PKCS#11 library path according to your environment.

  1. Execute the go code using the command below.

›_ Console

# go run rsa.go 
  1. Verify that keys are generated on HSM using below command.

›_ Console

# p11tool2 Slot=<slot_no.> LoginUser=ask ListObjects 
image-3285418261-1.jpg

List keys