c# - 获取所有连接的智能卡的列表

标签 c# interop x509certificate smartcard

我正在编写一个使用 x509 证书签署 XML 文档的类。我已经能够获得我的 SmartCard 证书并对其进行签名。

但是,为此我必须在 Windows Keystore 中查找 x509 证书,因此我必须知道一些关于我的智能卡的信息,例如发行者名称或序列号。这很好。

但我想要一种更方便的方法来获取智能卡证书。我有两个想法:

  • 从 Keystore 获取所有证书并寻找那些“来自智能卡”的证书。 But I dont think i'm able to get such information .
  • winscard.dll 互操作并获取有关连接到我的计算机的智能卡的一些信息,因此我可以使用它来查找正确的证书,但这不起作用:

    [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?

如何获得智能卡证书来签署 XML 消息?如果您想给我一个额外的答案,为什么我做的这个 Interop 不起作用?

最佳答案

我发现了一种仅使用 C# 即可知道 X509Certificate 是否来自智能卡的方法。这为我解决了问题,自从我编写代码以来已经有一段时间了,我删除了互操作 C# 和 C++ 代码。这对我有用:

if (certificate.HasPrivateKey)
{
    ICspAsymmetricAlgorithm aa = certificate.PrivateKey as ICspAsymmetricAlgorithm;

    if (aa == null || !aa.CspKeyContainerInfo.HardwareDevice) 
         DoWhateverYouWant(certificate);
}

如果在代码运行的那一刻没有连接卡,对我来说不是问题。如果您想获得连接到您的 PC 的智能卡列表,可以使用 winscard native API。

关于c# - 获取所有连接的智能卡的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21333115/

相关文章:

c# - 向 IntPtr 添加偏移量

java - 如何获取java的X509Certificate中的策略标识符和基本约束的主体类型

.net - 安全网络套接字 (WSS) 证书签名

c# - 我可以访问内部类中的外部类对象吗

c# - 为什么attr_accessor创建了一个属性,而method只是一个方法?

c# - 这些 javascript include 定义有区别吗

c# - 运行时 C# 知道正在使用的是 32 位还是 64 位版本的 COM 接口(interface)

openssl - OpenSSL 证书错误

c# - 使用 Moq 模拟 TraceListener

c# - .NET 密码学中 SignData() 和 CreateSignature() 的区别