gpt4 book ai didi

python - 从 urllib2 或 httplib 访问需要 Safenet USB token 的页面

转载 作者:太空狗 更新时间:2023-10-29 21:58:13 33 4
gpt4 key购买 nike

当我有一个软件证书时,我喜欢这样。

import httplib

CLIENT_CERT_FILE = '/path/to/certificate.pem'
connection = httplib.HTTPSConnection('url-to-open', cert_file=CLIENT_CERT_FILE)
connection.request('GET', '/')
response = connection.getresponse()
print response.status
data = response.read()
print data

如何使用 Safenet USB token 执行相同的操作?

最佳答案

TL;DR there are significant caveats and security issues with doing this in Python.A working "solution" involves using a PKCS#11 library to read the certificate from the key, then somehow persisting the certificate on the disk, and finally passing the resulting file path to the request object.

There will also be differences with each security stick's particularities. Some sticks do not offer to store a certificate along with its private key (aka a .pfx or .p12 file) which will essentially make this solution unworkable. I didn't have access to a Safenet stick, so used my own, please bear this in mind.

解决这个问题需要大量的工作。您使用安全加密狗意味着您的客户端证书位于加密狗本身。因此,为了实现相同级别的功能,您需要编写代码从那里提取证书并将其提供给您的请求对象。

1。 Python 中支持 HTTPS 的库

您对使用 httplib(http.client for python 3.x)或 urllib 的要求引入了一个很大的警告,即证书在请求必须是磁盘上的一个文件(对于构建在它们之上的所有库也是如此,例如requests)。参见 cnelson's answer to How to open ssl socket using certificate stored in string variables in python出于这个原因(简而言之:这是因为 python 的 ssl 库使用了一个 native C 库,它不提供传递内存中的对象作为证书)。另见 next answer from Dima Tisnek详细说明不同程度的黑客技术可能的解决方法。

如果将您的证书(即使是临时的)写入磁盘对您来说是行不通的,因为您使用安全棒很可能是这样,那么它开始时看起来并不好。

2。从安全棒中获取证书

您最大的挑战是拿到目前位于安全棒内的证书。 Safenet 棒与许多其他棒一样,其核心是支持 PKCS#11 的智能卡。我建议你熟悉一下这些概念,但本质上,SmartCard 是一种标准化的芯片设计,而 PKCS#11 是一种与之接口(interface)的标准化协议(protocol)。 “标准化”当然有一些警告,因为许多供应商都提出了他们自己的实现,但它可能已经足够标准化以达到您的目的。这里的技巧是使用存储棒上可用的 PKCS#11 接口(interface)来提取证书的属性。这就是网络浏览器在使用存储证书在网站上使用 stick 进行身份验证时本质上所做的,因此您需要让您的 python 程序执行类似的操作。

2.1 选择 PKCS#11 库

不幸的是,搜索“python pkcs11”时只出现了几个库。我对其中任何一个都没有既得利益,并且可能存在其他不那么突出的。

python-pkcs11(pypigithubreference)提供了“PKCS#11 的高级 pythonic 实现”。整体上使用起来可能更容易,但可能缺乏兼容性和/或功能,具体取决于你想做什么,但我怀疑简单地检索证书可能没问题。

PyKCS11(pypigithubreference)另一方面是原生 PKCS#11 库的包装器,它将延迟调用。这是一个较低级别的,但看起来更完整,而且如果相关的话,还可以提供使用您的特定供应商的实现的优势。

2.2 示例代码

例如,我将使用 python-pkcs11 的用户友好型 API。请记住,此代码未经过全面测试(并已部分简化),仅用于说明总体思路。

import pkcs11
import asn1crypto.pem
import urllib.request
import tempfile
import ssl
import os

# this is OpenSC's implementation of PKCS#11
# other security sticks may come with another implementation.
# choose the most appropriate one
lib = pkcs11.lib('/usr/lib/pkcs11/opensc-pkcs11.so')
# tokens may be identified with various names, ids...
# it's probably rare that more than one at a time would be plugged in
token = lib.get_token(token_serial='<token_serial_value>')

pem = None
with token.open() as sess:
pkcs11_certificates = sess.get_objects(
{
pkcs11.Attribute.CLASS: pkcs11.ObjectClass.CERTIFICATE,
pkcs11.Attribute.LABEL: "Cardholder certificate"
})

# hopefully the selector above is sufficient
assert len(pkcs11_certificates) == 1

pkcs11_cert = pkcs11_certificates[0]
der_encoded_certificate = pkcs11_cert.__getitem__(pkcs11.Attribute.VALUE)
# the ssl library expects to be given PEM armored certificates
pem_armored_certificate = asn1crypto.pem.armor("CERTIFICATE",
der_encoded_certificate)

# this is the ugly part: persisting the certificate on disk
# i deliberately did not go with a sophisticated solution here since it's
# such a big caveat to have to do this...
certfile = tempfile.mkstemp()
with open(certfile[1], 'w') as certfile_handle:
certfile_handle.write(pem_armored_certificate.decode("utf-8"))

# this will instruct the ssl library to provide the certificate
# if asked by the server.
sslctx = ssl.create_default_context()
sslctx.load_cert_chain(certfile=certfile[1])
# if your certificate does not contain the private key, find it elsewhere
# sslctx.load_cert_chain(certfile=certfile[1],
# keyfile="/path/to/privatekey.pem",
# password="<private_key_password_if_applicable>")

response = urllib.request.urlopen("https://ssl_website", context=sslctx)

# Cleanup and delete the "temporary" certificate from disk
os.remove(certfile[1])

3。结语

我想说 Python 不会是使用安全棒进行 SSL 客户端身份验证的最佳选择。事实上,大多数 ssl 库都要求证书存在于磁盘上,这直接违背了使用安全棒的好处(有时是要求)。我很清楚这个答案并没有提供这个问题的完整解决方案,但希望能足够详细地揭示挑战,以便就是否进一步追求这个问题或寻找另一种方法做出有根据的决定。

无论如何,祝你好运。

关于python - 从 urllib2 或 httplib 访问需要 Safenet USB token 的页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36233685/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com