Reputation: 4544
I have a third-party application (which we don't want to use), that can extract certificates from our card reader with the private key, and insert it to store. As I said, we don't want to use it for many reasons, so we tried to read card reader directly through PKCS11. As we develop in C#, we use th PKCS11 Interop library to manage it. However, I cannot retrieve the associate private key linked to this certificate. How can I do it ?
Here's my code :
List<ObjectAttribute> objectAttributes = new List<ObjectAttribute>();
objectAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_CERTIFICATE));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE, false));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
//objectAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, UTF8Encoding.UTF8.GetBytes("Certificat d'Authentification CPS")));
//CurrentSession.FindObjectsInit(objectAttributes);
oObjCollection = CurrentSession.FindAllObjects(objectAttributes);
//if (oObjCollection.Count > 0)
foreach (var item in oObjCollection)
{
var oAttriVal = CurrentSession.GetAttributeValue(item, new List<CKA>() { CKA.CKA_VALUE, CKA.CKA_ID }).FirstOrDefault();
oResult = new X509Certificate2(oAttriVal.GetValueAsByteArray());
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadWrite);
store.Add(oResult);
store.Close();
}
If I try to retrieve the private key, I can, but it is not readable, else I cannot see how to associate it to my retrieved certificate ?
List<ObjectAttribute> objectAttributes = new List<ObjectAttribute>();
objectAttributes = new List<ObjectAttribute>();
objectAttributes = new List<ObjectAttribute>();
objectAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_RSA));
CurrentSession.FindObjectsInit(objectAttributes);
var oObjCollection = CurrentSession.FindObjects(1);
if (oObjCollection.Count > 0)
{
oPrivKeyObjectHandle = oObjCollection[0];
}
List<ObjectAttribute> privKeyAttributes = new List<ObjectAttribute>();
if (oPrivKeyObjectHandle != null)
{
List<CKA> privKeyAttrsToRead = new List<CKA>();
privKeyAttrsToRead.Add(CKA.CKA_LABEL);
privKeyAttrsToRead.Add(CKA.CKA_ID);
privKeyAttrsToRead.Add(CKA.CKA_VALUE);
privKeyAttrsToRead.Add(CKA.CKA_VALUE_BITS);
privKeyAttributes = CurrentSession.GetAttributeValue(oPrivKeyObjectHandle, privKeyAttrsToRead);
}
CurrentSession.FindObjectsFinal();
Thanks for helping
Upvotes: 0
Views: 4282
Reputation: 4544
I finally managed to make it works.
My procedure is the following : I used third party software to analyse private key of the certificate put in store.
When I do so, I load CspParameters from the third party DLL like this :
var oParams = new CspParameters(1, "ASIP Sante Cryptographic Provider");
oParams.Flags = CspProviderFlags.UseExistingKey;
oParams.KeyNumber = (int)KeyNumber.Signature;
oParams.KeyContainerName = System.Text.RegularExpressions.Regex.Replace(GetAttributeValue(item, CKA.CKA_SUBJECT).First().GetValueAsString(), @"[^\u0020-\u007E]", string.Empty);
In my specific case, the KeyContainerName was the subject with only ASCII chars (it is NOT a default scenario).
When I create RSACryptoServiceProvider with this CSP, it works great, and I finally can not use third party application.
Note that ASIP Sante Cryptographic Provider is the provider installed with the third party software, that comes with a specific DLL for Windows CSP.
This code might not be compatible with Mono, Linux/Mac ...
Upvotes: 0
Reputation: 46095
In most cases you don't - most PKCS#11 devices won't let you extract the private key from the device and that's for a reason.
The "driver" that you are referring to most likely doesn't extract the key but makes it possible to use the private key by calling signing and decryption functions on the device when the system needs to perform such operation. This is done by the CSP module that many vendors provide.
You will need to do the same, i.e. most likely you won't be able to use CryptoAPI for operations without writing your own CSP (cryptographic services provider) which will do the same that your third-party application does.
Upvotes: 1