Reputation: 820
I am generating a RSA key pair with AWS cloud HSM with PKCS11Interop c# library on top of AWS vendor PKCS library. Wanted to export a public key from HSM with PKCS 11 getAttributeValue methods.
The response states that attributes cannot be read, I have marked all the attributes values correctly to be able to export a key, can somebody point out what I am doing wrong ?
My sample code
private static void GenerateRSAKeyPair(ISession session, out IObjectHandle publicKeyHandle, out IObjectHandle privateKeyHandle, string keyAlias = null)
{
byte[] ckaId = null;
if (string.IsNullOrEmpty(keyAlias))
ckaId = session.GenerateRandom(20);
else
ckaId = Encoding.UTF8.GetBytes(keyAlias);
// Prepare attribute template of new public key
List<IObjectAttribute> publicKeyAttributes = new List<IObjectAttribute>();
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_TOKEN, true));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY));
//publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_PRIVATE, false)); // Throws InvalidAttribute Value
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_ID, ckaId));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_WRAP, true));
//publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_SENSITIVE, true));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_MODULUS_BITS, 2048));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_PUBLIC_EXPONENT, new byte[] { 0x01, 0x00, 0x01 }));
// Prepare attribute template of new private key
List<IObjectAttribute> privateKeyAttributes = new List<IObjectAttribute>();
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_TOKEN, true));
//privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_PRIVATE, true));
//publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_SENSITIVE, true));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_ID, ckaId));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_UNWRAP, true));
// Specify key generation mechanism
IMechanism mechanism = session.Factories.MechanismFactory.Create(CKM.CKM_RSA_X9_31_KEY_PAIR_GEN);
// Generate key pair
session.GenerateKeyPair(mechanism, publicKeyAttributes, privateKeyAttributes, out publicKeyHandle, out privateKeyHandle);
}
private static byte[] GetKeyAttributeValue(ISession session, IObjectHandle keyHandle)
{
var readAttrs = session.GetAttributeValue(keyHandle, new List<CKA>() { CKA.CKA_VALUE });
if (readAttrs[0].CannotBeRead)
throw new Exception("Key cannot be exported");
else
return readAttrs[0].GetValueAsByteArray();
}
Upvotes: 0
Views: 829
Reputation: 820
As suggested by @Homaei
I have created below code to export a public key from c# code.
var modulus = GetKeyAttributeValue(session, publicKey, CKA.CKA_MODULUS);
var exponent = GetKeyAttributeValue(session, publicKey, CKA.CKA_PUBLIC_EXPONENT);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(dwKeySize: 2048);
RSAParameters rsaParam = rsa.ExportParameters(false);
rsaParam.Modulus = modulus;
rsaParam.Exponent = exponent;
rsa.ImportParameters(rsaParam);
var writer = System.IO.File.CreateText("exportedFromCode.txt");
//https://stackoverflow.com/questions/28406888/c-sharp-rsa-public-key-output-not-correct/28407693#28407693
ExportPublicKey(rsa, writer);
Upvotes: 0
Reputation: 175
RSA public key objects do not have CKA_VALUE
attribute. Instead, there are two attributes called CKA_MODULUS
and CKA_PUBLIC_EXPONENT
that make up the key value.
Upvotes: 3