.net core Pkcs11Interop空插槽列表

.net core Pkcs11Interop空插槽列表,.net-core,windows-services,pkcs11interop,.net Core,Windows Services,Pkcs11interop,我最近创建了一个控制台应用程序,其中包含Pkcs11Interop库的上下文以及HSM dll。它工作得很好,但是我需要将代码重写到Windows服务(因为它是.NET核心,所以我将它作为gRPC服务托管)。托管WS后,它发现factories.Pkcs11LibraryFactory.LoadPkcs11Library(factories,libraryPath,AppType.multi-threaded)上的插槽列表。GetSlotList(SlotsType.without或withou

我最近创建了一个控制台应用程序,其中包含Pkcs11Interop库的上下文以及HSM dll。它工作得很好,但是我需要将代码重写到Windows服务(因为它是.NET核心,所以我将它作为gRPC服务托管)。托管WS后,它发现factories.Pkcs11LibraryFactory.LoadPkcs11Library(factories,libraryPath,AppType.multi-threaded)上的插槽列表。GetSlotList(SlotsType.without或without-tokenpresent)。Find(slot=>slot.SlotId==SlotId)返回插槽的空列表,即使它在控制台应用程序中返回了3个元素的列表

    public Pkcs11Signature(string libraryPath, ulong slotId)
    {
        Pkcs11InteropFactories factories = new Pkcs11InteropFactories();
        _pkcs11Library = factories.Pkcs11LibraryFactory.LoadPkcs11Library(factories, libraryPath, AppType.MultiThreaded);
        _slot = _pkcs11Library.GetSlotList(SlotsType.WithOrWithoutTokenPresent).Find(slot => slot.SlotId == slotId);
    }
    
    public Pkcs11Signature Select(string alias, string certLabel, string pin, bool login)
    {
        List<CKA> pkAttributeKeys = new List<CKA>();
        pkAttributeKeys.Add(CKA.CKA_KEY_TYPE);
        pkAttributeKeys.Add(CKA.CKA_LABEL);
        pkAttributeKeys.Add(CKA.CKA_ID);
        List<CKA> certAttributeKeys = new List<CKA>();
        certAttributeKeys.Add(CKA.CKA_VALUE);
        certAttributeKeys.Add(CKA.CKA_LABEL);

        //CloseSession();            

        _session = _slot.OpenSession(SessionType.ReadWrite);
        if (login)
            _session.Login(CKU.CKU_USER, pin);

        ObjectAttributeFactory objectAttributeFactory = new ObjectAttributeFactory();

        List<IObjectAttribute> attributes = new List<IObjectAttribute>();
        attributes.Add(objectAttributeFactory.Create(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
        List<IObjectHandle> keys = _session.FindAllObjects(attributes);

        bool found = false;
        foreach (IObjectHandle key in keys)
        {
            List<IObjectAttribute> keyAttributes = _session.GetAttributeValue(key, pkAttributeKeys);

            ulong type = keyAttributes[0].GetValueAsUlong();
            string encryptionAlgorithm;
            switch (type)
            {
                case (ulong)CKK.CKK_RSA:
                    encryptionAlgorithm = "RSA";
                    break;
                case (ulong)CKK.CKK_DSA:
                    encryptionAlgorithm = "DSA";
                    break;
                case (ulong)CKK.CKK_ECDSA:
                    encryptionAlgorithm = "ECDSA";
                    break;
                default:
                    continue;
            }

            string thisAlias = keyAttributes[1].GetValueAsString();

            if (thisAlias == null || thisAlias.Length == 0)
                thisAlias = keyAttributes[2].GetValueAsString();
            if (alias != null && !alias.Equals(thisAlias))
                continue;

            attributes.Clear();
            attributes.Add(objectAttributeFactory.Create(CKA.CKA_CLASS, CKO.CKO_CERTIFICATE));
            attributes.Add(objectAttributeFactory.Create(CKA.CKA_CERTIFICATE_TYPE, CKC.CKC_X_509));

            if (certLabel == null && thisAlias != null && thisAlias.Length > 0)
                certLabel = thisAlias;
            if (certLabel != null)
                attributes.Add(objectAttributeFactory.Create(CKA.CKA_LABEL, certLabel));

            List<IObjectHandle> certificates =_session.FindAllObjects(attributes);

            if (certificates.Count != 1)
                continue;

            IObjectHandle certificate = certificates[0];
            List<IObjectAttribute> certificateAttributes =_session.GetAttributeValue(certificate, certAttributeKeys);
            X509Certificate x509Certificate =
                new X509Certificate(X509CertificateStructure.GetInstance(certificateAttributes[0].GetValueAsByteArray()));

            List<X509Certificate> x509Certificates = new List<X509Certificate>();
            x509Certificates.Add(x509Certificate);
            attributes.Clear();
            attributes.Add(objectAttributeFactory.Create(CKA.CKA_CLASS, CKO.CKO_CERTIFICATE));
            attributes.Add(objectAttributeFactory.Create(CKA.CKA_CERTIFICATE_TYPE, CKC.CKC_X_509));
            List<IObjectHandle> otherCertificates =_session.FindAllObjects(attributes);
            foreach (IObjectHandle otherCertificate in otherCertificates)
            {
                if (!certificate.ObjectId.Equals(otherCertificate.ObjectId))
                {
                    certificateAttributes =_session.GetAttributeValue(otherCertificate, certAttributeKeys);
                    X509Certificate otherX509Certificate =
                        new X509Certificate(X509CertificateStructure.GetInstance(certificateAttributes[0].GetValueAsByteArray()));
                    x509Certificates.Add(otherX509Certificate);
                }
            }

            found = true;
            _alias = thisAlias;
            _encryptionAlgorithm = encryptionAlgorithm;
            _privateKeyHandle = key;
            _chain = x509Certificates.ToArray();
            break;
        }

        if (!found)
        {
            Console.WriteLine("Havent found");
            _alias = null;
            _encryptionAlgorithm = null;
            _privateKeyHandle = null;
            _chain = null;
        }

        return this;
    }
我已经看到了这一点,但将Windows服务的“登录身份”更改为“本地服务”不会产生任何效果:

Pkcs11Interop通过调用非托管PKCS 11库的
C#u GetSlotList
函数返回接收到的插槽。因此,如果您得到0个插槽,那么
C_GetSlotList
将返回0个插槽。您需要与PKCS#11库的供应商讨论这种情况,他们可能知道为什么他们的库没有看到任何插槽。

我刚才看到了。windows服务提供的插槽数与控制台应用程序的插槽数不同的情况在供应商方面也存在问题吗?@Kokos34我们只需说,库供应商最了解库中发生的事情,以及它看到插槽的原因。
    using (var signature = new Pkcs11Signature(@"C:\Program Files (x86)\hsm\hsm.dll", 3).
        Select(null, "CERT LABEL", "PIN", true)
    {
        (...DO THE WORK HERE...)
    }