我正在尝试从PIV智能卡中提取以下内容:
我正在使用RedHat 6(最终是7)和CoolKey作为我的PKCS11模块。
我需要一种方法,可以通过代码提取此信息而无需使用智能卡针,无论是从Shell命令还是从智能卡库中获取。目前,我可以使用shell命令'pkcs11-tools --module -T'来获得通用名称,因此主题替代名称确实是我所追求的,但是我想找到一种更好的方式来获得通用名称(如果可用) 。
我知道此信息无需输入图钉即可使用,因为我可以在RHEL(esc)上随附的Smartcard Manager中查看所有信息。如果有的话,我有根,中级和下级的证书链。
我的想法是我必须从卡中提取证书,并使用本地CA验证该证书,然后对其进行解密。我花了几天的时间阅读有关APDU,智能卡和openssl的文档,却一无所获。
这是打开卡并查看详细信息时智能卡查看器显示的内容。我要从卡中提取Microsoft主体名称,以及在“层次结构”部分以及其他位置显示的“通用名称”,并以红色文字显示。
从那以后我实际上已经切换到使用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智能卡工具手动输入替代名称。
我可以使用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]”,但我不确定为什么这样做,因此我对其进行了操作以消除此问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句