使用不带令牌密码的Pkcs11Interop创建签名



我使用Pkcs11Interop与usb棒上的证书相结合来签署pdf文档。

执行以下步骤签署文件:

  • 加载pkcs11库(LoadPkcs11Library(
  • 获取所选智能卡/usb令牌的插槽
  • 插槽上的OpenSession(需要插槽引脚(
  • 在会话上执行登录
  • 搜索私钥句柄
  • 签署文档(需要密码(

对应代码:

private byte[] GetSignatureFromHashViaPkcs11(byte[] hash, string pin)
{
Pkcs11InteropFactories factories = new Pkcs11InteropFactories();
using (IPkcs11Library pkcs11Library = factories.Pkcs11LibraryFactory.LoadPkcs11Library(factories, PKCS11LibPath, AppType.SingleThreaded))
{
ISlot slot = LoadSlot(pkcs11Library, CertificateToUse.BelongsToSmartCardSlot.TokenSerial);
using (ISession session = slot.OpenSession(SessionType.ReadOnly))
{
session.Login(CKU.CKU_USER, pin);
//Search the private key based on the pulblic key CKA_ID
IObjectHandle keyHandle = null;
var searchTemplate = new List<IObjectAttribute>()
{
//CKO_PRIVATE_KEY in order to get handle for the private key
session.Factories.ObjectAttributeFactory.Create(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY),
//CKA_ID searching for the private key which matches the public key
session.Factories.ObjectAttributeFactory.Create(CKA.CKA_ID, CertificateToUse.PublicKeyCKAID.GetValueAsByteArray()),
};
//filter the search result. Since we search for a private key, only one is returned for each certificate
var search = session.FindAllObjects(searchTemplate);
keyHandle = search.FirstOrDefault();
if (keyHandle == null || (keyHandle.ObjectId == CK.CK_INVALID_HANDLE))
{
throw new Exception("Unable to read SmartCard KeyHandle. Make sure the correct PKCS11 Library is used");
}
try
{
//Create the signature (using the pin)
var pinAsByteArray = UTF8Encoding.UTF8.GetBytes(pin);
using (IMechanism mechanism = session.Factories.MechanismFactory.Create(CKM.CKM_SHA256_RSA_PKCS))
return session.Sign(mechanism, keyHandle, pinAsByteArray, hash);
}
catch (Exception ex)
{
throw new Exception("Error creating the signature", ex);
}
}
}
}

如果插槽引脚和私钥引脚相同,则此解决方案有效。如果这些引脚不同,则上述代码不起作用,因为只使用了一个引脚。

如果我在代码中手动管理插槽引脚和私钥引脚,一切都会正常工作。

但似乎可以创建签名,而无需之前执行OpenSession。我的客户有一个旧工具,它只需要私钥针就可以签署文档(这意味着从技术上讲,在没有槽针的情况下签署是可能的(。

我的问题是,我目前需要进行会话。使用插槽引脚登录以获得私钥句柄。

问题:有没有其他方法可以使用Pkcs11Interop签署文件,而无需首先进行会话。登录。或者有没有其他方法可以在不需要首先进行会话的情况下获得私钥句柄。登录?

如果客户不愿意信任您的插槽引脚,也许您可以构建一个中间适配器服务,该服务反过来可以执行签名并将此功能发布为具有某种身份验证的api,您可以将有效负载传递到该api中,它将对其进行签名并返回。

然后,客户端可以自由管理中间组件,并使用插槽引脚对其进行初始化。

最新更新