从 PIV 智能卡中提取名称

Posted

技术标签:

【中文标题】从 PIV 智能卡中提取名称【英文标题】:Extract names from PIV smartcard 【发布时间】:2020-09-03 16:52:02 【问题描述】:

我正在尝试从 PIV 智能卡中提取以下内容:

    主题通用名 证书主题替代名称/Microsoft 主体名称

我使用 RedHat 6(最终是 7)和 CoolKey 作为我的 PKCS11 模块。

我需要一种方法来通过代码提取此信息,而不需要智能卡引脚,无论是来自 shell 命令还是智能卡库。目前我可以通过使用 shell 命令 'pkcs11-tools --module -T' 来获取通用名称,因此主题替代名称确实是我所追求的,但我想找到一种更好的方法来获取通用名称(如果可用) .

我知道此信息无需输入密码即可使用,因为我可以在 RHEL (esc) 上包含的智能卡管理器中查看所有信息。如果这很重要,我有根证书链、中间证书链和从属证书链。

我的想法是我必须从卡中提取证书,使用我的本地 CA 验证该证书,然后对其进行解密。我花了几天时间阅读有关 APDU、智能卡和 openssl 的文档,但一无所获。

编辑 RHEL 智能卡管理器视图:

这是您打开卡并查看详细信息时智能卡查看器显示的内容。 Microsoft Principal Name 是我希望从卡片中提取的内容,以及显示在 Hierarchy 部分和其他位置的“通用名称”,由红色文本显示。

我实际上已经切换到使用 pkcs15-tool,因为 pkcs11-tool 截断了更长的常用名称(您可以在屏幕截图的标题栏中看到这一点,同样的问题)。 输出:'pkcs15-tool --list-info'

Using reader with a card: <reader name>
PKCS#15 Card [LASTNAME.FIRSTNAME.MIDDLENAME.12345678]:
        Version          : 0
        Serial number    : <big string>
        Manufacturer ID  : piv_II
        Flags            :

我当前的方法是简单地将括号中的字符串解析为通用名称,并让用户使用 Redhat 智能卡工具手动输入 Alt Name。

【问题讨论】:

查看PIV specification 我找不到术语主题通用名 我猜他是指存储在卡上的一个或所有证书的主题 CN。 Subject Common Name 是 Redhat 智能卡管理器所称的,它是插入卡时在 GUI 中显示的名称。运行 pkcs11-tool -T 时,它被列为“令牌标签”。也许这在 PIV 规范的第 41 页上被列为“名称”?至于替代名称,我看到的唯一提及是在第 26 页。 pkcs11-tool 显示的“令牌标签”可以通过C_GetTokenInfo 提取(参见here)。您能否编辑您的答案以包括 pkcs11-tool 的输出和 Redhat 智能卡管理器显示的屏幕截图。一旦我们确定了您正在寻找的内容,我可以为 PKCS#11 提供更具体的代码示例。 【参考方案1】:

通过使用 Java bouncycastle 和 iaik pkcs11 包装器,我能够获得通用名称和 UPN/证书替代名称。

//path to .so library file
Module pkcs11Module = Module.getInstance(this.getProperties().getProperty("PKCS11_LIBRARY"));
pkcs11Module.initialize(null);
Slot[] slotsWithToken = pkcs11Module.getSlotList(Module.SlotRequirement.TOKEN_PRESENT);
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
for(Slot s : slotsWithToken)    
    Session session = s.getToken().openSession(Token.SessionType.SERIAL_SESSION, Token.SessionReadWriteBehavior.RO_SESSION, null, null);
    session.findObjectsInit(new X509PublicKeyCertificate());
    Object[] objects = null;
    while((objects = session.findObjects(1)).length > 0)    
        for(Object c : objects) 
            X509PublicKeyCertificate cert = (X509PublicKeyCertificate) c;
            byte[] certValue = cert.getValue().getByteArrayValue();
            Certificate cc = certFactory.generateCertificate(new ByteArrayInputStream(certValue));
            if(cc instanceof X509Certificate)   
                X509Certificate x509 = (X509Certificate) cc;
                //COMMON NAME:
                String name = new X500Name(x509.getSubjectDN().getName()).getRDNs()[0].getFirst().getValue().toString();
                Collection<List<?>> altNames = x509.getSubjectAlternativeNames();
                for(List<?> list : altNames)    
                    ASN1Sequence seq = ASN1Sequence.getInstance(new ASN1InputStream(new ByteArrayInputStream((byte[]) list.get(1))).readObject());
                    ASN1TaggedObject obj = (ASN1TaggedObject) seq.getObjectAt(1);
                    //ALT NAME:
                    String upn = obj.getObject().toString();
                    upn = upn.substring(upn.lastIndexOf("]") + 1);
                
            
        
    

upn 前面附加了“[0]”,我不确定这是为什么,所以我对其进行了操作以消除它。

【讨论】:

以上是关于从 PIV 智能卡中提取名称的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中从智能卡中读取名称和地址等基本数据?

人工智能轨道交通行业报告下载(2022)

人工智能轨道交通行业报告下载(2022)

第十六届全国大学生智能车竞赛报名信息统计

人工智能我见及特征提取mfcc算法理解

智能识别系统设计---图像特征提取