Pkcs11Interop / Pkcs11Interop.X509Store

Easy to use PKCS#11 based X.509 certificate store
Apache License 2.0
31 stars 18 forks source link

Private Key #2

Closed ozerkaya closed 5 years ago

ozerkaya commented 5 years ago

First of all, congratulations on sharing. very successful business. My problem is I can't get the private key.

Slot slot;
using (Pkcs11 pkcs11 = new Pkcs11(@"C:\Windows\System32\akisp11.dll", AppType.SingleThreaded))
{
    List<Slot> slots = pkcs11.GetSlotList(SlotsType.WithOrWithoutTokenPresent);
    slot = slots[0];

    using (Session session = slot.OpenSession(SessionType.ReadOnly))
    {
        session.Login(CKU.CKU_USER, "000000");

        List<ObjectAttribute> searchTemplate = new List<ObjectAttribute>();
        searchTemplate.Add(new ObjectAttribute(CKA.CKA_CLASS, (uint)CKO.CKO_CERTIFICATE));

        List<ObjectHandle> certObjectHandles = session.FindAllObjects(searchTemplate);

        foreach (ObjectHandle certObjectHandle in certObjectHandles)
        {
            List<CKA> attributes = new List<CKA>();
            attributes.Add(CKA.CKA_VALUE);

            List<ObjectAttribute> objectAttributes = session.GetAttributeValue(certObjectHandle, attributes);

            byte[] certData = objectAttributes[0].GetValueAsByteArray();

            X509Certificate2 x509Certificate2 = new X509Certificate2(certData);     

            RSA rsaPrivateKey = x509Certificate2.GetRSAPrivateKey();

            //PRIVATE KEY NULL ?
        }

        session.CloseSession();
        list.Add(new kayit
        {
            Base64 = bytesStr
        });
    }
}
jariq commented 5 years ago

This code won't work because when you construct X509Certificate2 this way it does not have any private key associated with it:

byte[] certData = objectAttributes[0].GetValueAsByteArray();
X509Certificate2 x509Certificate2 = new X509Certificate2(certData);     
RSA rsaPrivateKey = x509Certificate2.GetRSAPrivateKey();

You can try to use Pkcs11Interop.X509Store library (that's where you opened this issue) and use GetRSAPrivateKey method on Pkcs11X509Certificate class instead.

ozerkaya commented 5 years ago

@jariq thanks for reply. Yesterday all time I work for this issue but i cant take private key in usb hardware. I dont have a HSM. I have a usb hardware this is image: http://mm.kamusm.gov.tr/surecler/aldim_ne_yapmaliyim/1.jpg

I can not create PinProvider. Can you give a sample ? how can I use Pkcs11Interop.X509Store by new or external projects for private key ?

jariq commented 5 years ago

I can not create PinProvider. Can you give a sample?

You need to create your own class that implements IPinProvider interface. Simplest example:

using Net.Pkcs11Interop.Common;

namespace ConsoleApp1
{
    public class SimplePinProvider : IPinProvider
    {
        private byte[] _pin = null;

        public SimplePinProvider(string pin)
        {
            _pin = ConvertUtils.Utf8StringToBytes(pin);
        }

        public GetPinResult GetKeyPin(Pkcs11X509StoreInfo storeInfo, Pkcs11SlotInfo slotInfo, Pkcs11TokenInfo tokenInfo, Pkcs11X509CertificateInfo certificateInfo)
        {
            return new GetPinResult(false, _pin);
        }

        public GetPinResult GetTokenPin(Pkcs11X509StoreInfo storeInfo, Pkcs11SlotInfo slotInfo, Pkcs11TokenInfo tokenInfo)
        {
            return new GetPinResult(false, _pin);
        }
    }
}

How can I use Pkcs11Interop.X509Store by new or external projects for private key?

By referencing Pkcs11Interop.X509Store nuget package.