【问题标题】:How to use a private key that is stored on an HSM that is secured by a user password via Pkcs11Interop OR CNG?如何使用通过 Pkcs11Interop 或 CNG 由用户密码保护的 HSM 上存储的私钥?
【发布时间】:2019-08-02 10:29:40
【问题描述】:

总结

使用 CNG 或 Pkcs11Interop 或任何其他替代方法登录 HSM,搜索私钥,然后将其传递给第 3 方应用程序以供使用。 密钥无法从 HSM 中提取或存储在内存中。

第 3 方应用程序需要使用存储在硬件安全模块 (HSM) 上的私钥。 我研究了两种方法 CNG 和 Pkcs11Interop。

代码需要完成以下工作:

1-验证并与 HSM 建立会话

2-搜索密钥

3-使用 RSACryptoServiceProvider 或其他方法将私钥传递给第 3 方。

重要提示:无法从 HSM 中提取或直接访问密钥(出于安全目的而设计)。

以下是我为 CNG 和 PKCS11Interop 制作的两个示例

问题:

1-CNG 我正在努力进行身份验证(如果可能的话)

2-PKCS11Interop 我已经能够登录,搜索密钥但难以使用密钥。

很高兴使用这两种方法,我欢迎任何帮助、替代解决方案或建议。

CNG 代码: 此代码在 HSM 上禁用身份验证时有效

问。有没有办法使用密码进行身份验证,在使用密钥之前打开会话?

CngProvider provider = new CngProvider("CNGProvider");
const string KeyName = "somekey";
key = CngKey.Open(KeyName, provider);
Console.WriteLine("found the key!");
var cngRsa = new RSACng(key);
var privateSshKey = new SshPrivateKey(cngRsa);

PKCS11Interop,我设法进行身份验证,搜索密钥并将其分配给句柄..

问。如何将私钥传递给标准的 .Net Framework 类型的 AsymmetricAlgorithm?同时记住它不可出口? 它可以传递给 RSACryptoServiceProvider 吗?然后是非对称算法?

using (IPkcs11Library pkcs11Library = Settings.Factories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Factories, Settings.Pkcs11LibraryPath, Settings.AppType))
        {
            ISlot slot = Helpers.GetUsableSlot(pkcs11Library);
            using (ISession session = slot.OpenSession(SessionType.ReadWrite))
            {
                //search for key
                try
                {
                const string keyname = "somekey";
                // Login as normal user
                session.Login(CKU.CKU_USER, Settings.NormalUserPin);
                IObjectHandle publicKeyHandle = Helpers.CreateDataObject(session);
                IObjectHandle privateKeyHandle = Helpers.CreateDataObject(session);
                // Prepare attribute template that defines search criteria
                List<IObjectAttribute> privateKeyAttributes = new List<IObjectAttribute>();
                privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
                privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_KEY_TYPE, CKK.CKK_RSA));
                privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_LABEL, keyname));

                List<IObjectHandle> foundPrivateKeys = session.FindAllObjects(privateKeyAttributes);
                if (foundPrivateKeys == null || foundPrivateKeys.Count != 1)
                    throw new Exception("Unable to find private key");

                // Use found object handles
                 privateKeyHandle = foundPrivateKeys[0];
                session.FindObjectsFinal();

                // How do i go about using the privatekey handle here?

                session.DestroyObject(privateKeyHandle);
                session.Logout();
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("Crypto error: " + ex.Message);
                        }
                        Console.WriteLine("done!");
                        System.Console.Write("[Hit Enter to Continue]");
                        System.Console.ReadLine();

                    }
                }

【问题讨论】:

    标签: cryptography private-key pkcs#11 hsm pkcs11interop


    【解决方案1】:

    使用 HSM,根据设计,您不能“将私钥传递给第 3 方应用”。

    您也不能在进程之间传递密钥句柄(尽管这可能在某些实现中起作用 - 密钥句柄应该是 PKCS11 会话特定的)。

    您的第 3 方应用需要使用可配置的加密库(如 OpenSSL(或类似))将加密操作卸载到 HSM,或者如果它使用 CNG,它应该允许您配置提供程序。

    问。有没有办法使用密码进行身份验证,在使用密钥之前打开会话?

    答.:对于使用 CNG 的应用,您应该在配置后使用 HSM 供应商提供的 CNG 密钥存储提供程序 (KSP)。

    然后,HSM 供应商 KSP 将提示输入密码,或者,如果您将提供程序(使用来自 HSM 供应商的实用程序或配置文件)配置为存储密码/pin,它将正常工作.

    使用 NCryptNative 的 eHSM 示例代码:

        SafeNCryptProviderHandle handle;
        NCryptOpenStorageProvider(handle, "eHSM Key Storage Provider",0);
        ...
    

    问。如何将私钥传递给标准的 .Net Framework 类型的 AsymmetricAlgorithm?同时记住它不可出口?它可以传递给 RSACryptoServiceProvider 吗?然后是非对称算法?

    答.:不,您不能传递密钥材料,也不能将原始 PKCS11 句柄传递给 CNG 框架。您要么必须使用 PKCS11Interop 函数来执行所有加密操作,要么必须在 CNG 中执行所有操作(如上正确配置)。

    要直接使用 PKCS11 接口,您可以继续使用密钥句柄调用 PKCS11 函数,即。

        // How do i go about using the privatekey handle here?
    
        // something like this
        session.SignInit(mechanism, privateKeyHandle);
        session.Sign(data, signature));
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-09
      • 1970-01-01
      • 2012-08-06
      相关资源
      最近更新 更多