Pkcs11Interop 空槽列表
Pkcs11Interop empty slot list
我最近创建了一个控制台应用程序,它包含 Pkcs11Interop 库的上下文以及 HSM dll。它运行良好,但我需要将代码重写为 Windows 服务(我将其托管为 gRPC 服务,因为它是 .NET Core)。托管WS后,出现slot list on factories.Pkcs11LibraryFactory.LoadPkcs11Library(factories, libraryPath, AppType.MultiThreaded).GetSlotList(SlotsType.WithOrWithoutTokenPresent).Find(slot => slot.SlotId == slotId) returns 一个空的插槽列表,即使它在控制台应用程序中返回了 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;
}
正在执行库:
using (var signature = new Pkcs11Signature(@"C:\Program Files (x86)\hsm\hsm.dll", 3).
Select(null, "CERT LABEL", "PIN", true)
{
(...DO THE WORK HERE...)
}
我已经看到了,但是将 Windows 服务的“登录身份”更改为“本地服务”没有任何效果:
Pkcs11Interop returns 通过调用非托管 PKCS#11 库的 C_GetSlotList
函数接收的插槽。因此,如果您获得 0 个插槽,则 C_GetSlotList
返回 0 个插槽。您需要与 PKCS#11 库的供应商讨论这种情况,他们可能知道为什么他们的库看不到任何插槽。
我最近创建了一个控制台应用程序,它包含 Pkcs11Interop 库的上下文以及 HSM dll。它运行良好,但我需要将代码重写为 Windows 服务(我将其托管为 gRPC 服务,因为它是 .NET Core)。托管WS后,出现slot list on factories.Pkcs11LibraryFactory.LoadPkcs11Library(factories, libraryPath, AppType.MultiThreaded).GetSlotList(SlotsType.WithOrWithoutTokenPresent).Find(slot => slot.SlotId == slotId) returns 一个空的插槽列表,即使它在控制台应用程序中返回了 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;
}
正在执行库:
using (var signature = new Pkcs11Signature(@"C:\Program Files (x86)\hsm\hsm.dll", 3).
Select(null, "CERT LABEL", "PIN", true)
{
(...DO THE WORK HERE...)
}
我已经看到了,但是将 Windows 服务的“登录身份”更改为“本地服务”没有任何效果:
Pkcs11Interop returns 通过调用非托管 PKCS#11 库的 C_GetSlotList
函数接收的插槽。因此,如果您获得 0 个插槽,则 C_GetSlotList
返回 0 个插槽。您需要与 PKCS#11 库的供应商讨论这种情况,他们可能知道为什么他们的库看不到任何插槽。