使用智能卡证书和公钥的网站认证

Posted

技术标签:

【中文标题】使用智能卡证书和公钥的网站认证【英文标题】:Website authentication using smart cards' certificate and public key 【发布时间】:2020-02-17 15:42:15 【问题描述】:

所以我有一张看起来像带有芯片的智能卡的信用卡。此卡插入读卡器后登录网站。

现在我必须用 python 编写一个程序,它可以读取卡并登录该网站。经过网上研究,我发现我需要提取:

    证书和 公钥(因为无法提取私钥)

从卡中,然后使用这两个东西来创建一个 HTTPS 连接 (example here) 。到目前为止,我能够以 pem 格式提取证书。但到目前为止,我还没有找到一种方法来提取 pem 格式的密钥。我使用PyKCS11 读取卡片。以下是我的代码:

from asn1crypto import pem, x509
from PyKCS11 import *
import binascii

pkcs11 = PyKCS11Lib()
pkcs11.load(r'C:\Windows\System32\XXXX.dll')
print(pkcs11.getSlotList(tokenPresent=False))

slot = pkcs11.getSlotList(tokenPresent=False)[0]
print(pkcs11.getTokenInfo(slot))

session = pkcs11.openSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION)
session.login('123456')
result = []
result_pem = []



# find public key and print modulus
pubKey = session.findObjects([(CKA_CLASS, CKO_PUBLIC_KEY)])[0]
modulus = session.getAttributeValue(pubKey, [CKA_MODULUS])[0]
print("\nmodulus: ".format(binascii.hexlify(bytearray(modulus))))

#find certificates
certs = session.findObjects([(CKA_CLASS, CKO_CERTIFICATE)])
for cert in certs:
    cka_value, cka_id = session.getAttributeValue(cert, [CKA_VALUE, CKA_ID])
    cert_der = bytes(cka_value)
    cert = x509.Certificate.load(cert_der)
    # Write out a PEM encoded value
    cert_pem = pem.armor('CERTIFICATE', cert_der)
    result.append(cert)
    result_pem.append(cert_pem)
    with open('cert.pem','wb') as f:
         f.write(cert_pem)
print(result)

所以这是我的问题: 1. 我的做法对吗?

    如果是,那么如何提取pem格式的公钥?

    这种智能卡身份验证实际上是如何在客户端和服务器端工作的?

【问题讨论】:

请检查此答案***.com/a/55757349/9659885 是否有任何帮助...您的主机(服务器)可能会使用 python 来验证从本答案中讨论的浏览器扩展接收到的签名令牌。 【参考方案1】:

公钥提取

如果您已经导出了证书,从那里提取公钥可能比从智能卡中提取公钥更容易。您可以为此使用 openssl:

openssl x509 -in cert.pem -pubkey -out pubkey.pem -noout

认证

您想要实现的是使用客户端证书打开一个带有相互身份验证的 TLS 连接。如果您这样做,您的客户端证书的私钥会对握手的一部分进行签名,以向服务器验证自己。

从智能卡中提取证书和公钥对您没有帮助。您需要找到一个库,它允许您直接从您的 PKCS#11 令牌中使用您的私钥。

【讨论】:

感谢您的确认。不幸的是,我找不到允许您直接从 PKCS#11 令牌中使用私钥的 python3.x 库。有“M2crypto”,但它只支持 Python2.x 。似乎在python中是不可能的。你能推荐任何其他易于实现的编程语言吗? 我也不知道有任何现成的解决方案。我过去使用 C# 完成了它,但这需要一些自定义扩展。 Openssl 绝对可以做到,但这不能称为“简单”。 好的。我会追求openssl。无论如何,如果您知道任何关于如何在 openssl 中实现此功能的好文章,请告诉我。

以上是关于使用智能卡证书和公钥的网站认证的主要内容,如果未能解决你的问题,请参考以下文章

国密证书双向认证客户端发送哪个

HTTPS 升级指南

CA自建和证书申请

nginx和iis下的SSL双向认证教程【ca 自签 ssl证书】

公钥私钥和证书

苹果证书和公钥私钥加密