我正在编写一个使用x509证书签署XML文档的类。我已经能够获得我的智能卡证书并签名了。
但是,要做到这一点,我必须在Windows密钥库中查找x509证书,因此我必须了解我的智能卡,例如颁发者名称或序列号。那太好了。
但我想要一种更方便的方法来获得SmartCard证书。我有两个想法:
与winscard.dll
互操作并获取有关连接到我的计算机的SmartCard的一些信息,因此我可以使用它来查找正确的证书,但这不起作用:
[DllImport("winscard.dll")]
public static extern long SCardListCards(
uint hContext, int pbAtr,
int rgguidInterfaces, int cguidInterfaceCount,
[MarshalAs(UnmanagedType.LPTStr)] ref string mszCards,
ref int pcchCards);
[DllImport("winscard.dll")]
public static extern long SCardEstablishContext(uint dwScope,
int pvReserved1,
int pvReserved2,
ref uint phContext);
这是一种测试方法。 string crds
包含智能卡列表。
[TestMethod]
public void TestInterop()
{
uint handle = 0;
Interop.SCardEstablishContext(0, 0, 0, ref handle);
string crds = "";
int pcch = 0;
Interop.SCardListCards(handle, 0, 0, 0, ref crds, ref pcch);
Assert.IsTrue(crds != "");
}
此测试每次都失败,因为crds
永远不会改变。
如果我尝试将crds
作为byte[]
返回:
[DllImport("winscard.dll", EntryPoint = "SCardListCards")]
public static extern long SCardListCardsRetBytes(
uint hContext, int pbAtr,
int rgguidInterfaces, int cguidInterfaceCount,
ref byte[] mszCards,
ref int pcchCards);
我的byte[] crds
变为:
byte[] {171}
当我用byte[] crds = {};
初始化为什么171?byte[] {0}
当我用byte[] crds = new byte[32];
初始化它时为什么是0?如何获取SmartCard证书以签署XML消息?如果你想给我一个奖金答案,为什么我这样做的Interop不起作用?
答案 0 :(得分:0)
我发现了一种方法,可以知道X509Certificate
来自只使用C#的智能卡。这解决了我的问题,自从我编写代码以来已经有一段时间了,我删除了互操作C#和C ++代码。这对我有用:
if (certificate.HasPrivateKey)
{
ICspAsymmetricAlgorithm aa = certificate.PrivateKey as ICspAsymmetricAlgorithm;
if (aa == null || !aa.CspKeyContainerInfo.HardwareDevice)
DoWhateverYouWant(certificate);
}
如果在代码运行时卡未连接,对我来说不是问题。如果您想获得连接到PC的智能卡列表,可以使用winscard
本机API。