我正在编写一个类,使用x509证书对XML文档进行签名。我已经能够获取我的智能卡证书并对其进行签名。
然而,为了做到这一点,我必须在Windows密钥库中查找x509证书,因此我必须了解有关我的智能卡的一些信息,例如颁发者名称或序列号。这很好。
但是我想要更方便的方法来获取智能卡证书。我有两个想法:
- Get all the certificates from the Keystore and look for those who are "coming from a SmartCard". But I dont think i'm able to get such information.
Interop with
winscard.dll
and get some information about the SmartCard connected to my computer, so I could use it to find the right certificate, but this isn't working:[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[] crds = {};
初始化时,byte[] {171}
,为什么会是171? - 当我使用
byte[] crds = new byte[32];
初始化时,byte[] {0}
,为什么会是0?
我该如何获取智能卡证书来签署XML消息?如果您愿意给我一个额外的答案,为什么我进行的Interop不起作用?
SCardListCards
没有返回智能卡列表,可能是因为您在错误的域中搜索它们。 尝试在系统上下文中搜索智能卡,而不是用户上下文。 例如:Interop.SCardEstablishContext(2, 0, 0, ref handle);
- ClotzASCardListCards
两次:第一次是为了获取缓冲区长度,第二次才是真正填充缓冲区。 可以参考这个例子:http://www.pinvoke.net/default.aspx/winscard.scardestablishcontext - ClotzA