概括
使用 CNG 或 Pkcs11Interop 或任何其他替代方法登录 HSM,搜索私钥,然后将其传递给第 3 方应用程序以供使用。密钥无法从 HSM 中提取或存储在内存中。
第三方应用程序需要使用存储在硬件安全模块 (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();
}
}