我正在尝试使用 Pkcs11Interop 使用 C# 应用程序中智能卡证书中的私钥对消息进行签名。我们使用的智能卡包含多个证书——通常一个用于签名,一个用于身份验证。如果我使用 X509Certificate2,我会根据我正在寻找的 X509KeyUsageFlags 过滤证书。我正在努力弄清楚如何使用 PKCS11 来解决这个问题。
我开始的代码如下。当我调用 session.FindAllObjects 时,我在结果中获得了 2 个证书(这是预期的,因为这是智能卡上有多少个证书。)
我尝试使用 GetAttributeValue 读取各种属性,看看是否可以使用它们来识别正确的证书 - 奇怪的是,它们都返回 null/0 值。查询 CKA_SENSITIVE 属性返回 True (这也是预期的),但显然我无法从对象中读取其他属性。
我在使用 GetAttributeValue 时做错了什么吗?还是有其他方法我应该解决这个问题?
public byte[] SignMessage(byte[] message, string pin)
{
var factories = new Pkcs11InteropFactories();
using (IPkcs11Library pkcs11Library = factories.Pkcs11LibraryFactory.LoadPkcs11Library(factories, DriverPath, AppType.SingleThreaded))
{
ISlot slot = GetSlot(pkcs11Library);
if (slot == null)
{
return null;
}
using (ISession session = slot.OpenSession(SessionType.ReadWrite))
{
session.Login(CKU.CKU_USER, pin);
var searchTemplate = new List<IObjectAttribute> {
factories.ObjectAttributeFactory.Create(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY),
factories.ObjectAttributeFactory.Create(CKA.CKA_KEY_TYPE, CKK.CKK_RSA),
factories.ObjectAttributeFactory.Create(CKA.CKA_SIGN, true),
};
List<IObjectHandle> foundObjects = session.FindAllObjects(searchTemplate); // foundObjects.Count = 2!
IObjectHandle privateKey = foundObjects.FirstOrDefault();
var readResult = session.GetAttributeValue(privateKey, new List<CKA>() { CKA.CKA_LABEL });
var label = readResult[0].GetValueAsString(); // label ends up being null!
byte[] result = null;
using (IMechanism signingMechanism = session.Factories.MechanismFactory.Create(CKM.CKM_SHA256_RSA_PKCS))
{
result = session.Sign(signingMechanism, privateKey, message);
}
session.DestroyObject(privateKey);
session.Logout();
return result;
}
}
}