Итак, у меня есть кредитная карта, похожая на смарт-карту с чипом. Эта карта регистрируется на веб-сайте после того, как карта вставлена в устройство чтения карт.
Теперь мне нужно написать программу на python, которая может считывать карту и выполнять вход на этом веб-сайте. После исследования inte rnet я обнаружил, что мне нужно извлечь сертификат с карты, а затем использовать его для создания HTTPS-соединения. До сих пор я могу извлечь сертификат в формате 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))
# get slot value via pkcs11.getSlotList(tokenPresent=False). Usually it's 0
session = pkcs11.openSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION)
session.login('123456')
result = []
result_pem = []
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)
Теперь я отправляю HTTPS-запрос с извлеченным сертификатом карты и ПИН-кодом карты. Ниже мой код:
import http.client
import json
import ssl
# Defining certificate related stuff and host of endpoint
certificate_file = r'C:\Users\XXXXX\Documents\Reporting Tool\cert.pem'
certificate_secret= '123456'
host = "example.com"
# Defining parts of the HTTP request
request_url='/login.form'
request_headers = {
'user-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36'
}
request_body_dict={
'login-form-type': 'cert'
}
# Define the client certificate settings for https connection
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.load_cert_chain(certfile=certificate_file, password=certificate_secret) ##gives error
Последняя строка этого кода выдает ошибку:
Exception has occurred: SSLError
[SSL] PEM lib (_ssl.c:3845)
Итак, вот мои вопросы:
- Подход правильно?
- Если да, то как исправить эту ошибку?