Pkcs11Interop を使用して、C# アプリケーションでスマート カード証明書の秘密キーを使用してメッセージに署名しようとしています。使用しているスマート カードには複数の証明書が含まれています。通常、1 つは署名用で、もう 1 つは認証用です。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;
}
}
}