首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用没有令牌密码的Pkcs11Interop创建签名

使用没有令牌密码的Pkcs11Interop创建签名
EN

Stack Overflow用户
提问于 2022-03-28 13:53:06
回答 1查看 307关注 0票数 2

我正在使用Pkcs11Interop结合一个证书在usb棒上签署pdf文件。

执行下列步骤对文档进行签名:

在session (LoadPkcs11Library)

  • Get上加载所选智能卡/usb token

  • OpenSession的插槽(需要插槽)

  • 在会话

  • 上执行登录,搜索私钥句柄

  • 签名文档(需要引脚)

<代码>F 213

相应代码:

代码语言:javascript
复制
  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的情况下创建签名。我的客户有一个旧工具,它只需要私钥引脚来签署文档(这意味着在技术上可以不用插槽引脚进行签名)。

我的问题是,为了获得私钥句柄,我目前需要用插槽引脚做session.Login。

问:是否有另一种方法可以使用Pkcs11Interop对文档进行签名,而不必先执行session.Login。或者,是否有另一种无需首先执行session.Login即可获得私钥句柄的方法?

EN

回答 1

Stack Overflow用户

发布于 2022-04-06 19:02:44

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71648639

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档