- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
当我有一个软件证书时,我喜欢这样。
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.
解决这个问题需要大量的工作。您使用安全加密狗意味着您的客户端证书位于加密狗本身。因此,为了实现相同级别的功能,您需要编写代码从那里提取证书并将其提供给您的请求对象。
您对使用 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详细说明不同程度的黑客技术可能的解决方法。
如果将您的证书(即使是临时的)写入磁盘对您来说是行不通的,因为您使用安全棒很可能是这样,那么它开始时看起来并不好。
您最大的挑战是拿到目前位于安全棒内的证书。 Safenet 棒与许多其他棒一样,其核心是支持 PKCS#11 的智能卡。我建议你熟悉一下这些概念,但本质上,SmartCard 是一种标准化的芯片设计,而 PKCS#11 是一种与之接口(interface)的标准化协议(protocol)。 “标准化”当然有一些警告,因为许多供应商都提出了他们自己的实现,但它可能已经足够标准化以达到您的目的。这里的技巧是使用存储棒上可用的 PKCS#11 接口(interface)来提取证书的属性。这就是网络浏览器在使用存储证书在网站上使用 stick 进行身份验证时本质上所做的,因此您需要让您的 python 程序执行类似的操作。
不幸的是,搜索“python pkcs11”时只出现了几个库。我对其中任何一个都没有既得利益,并且可能存在其他不那么突出的。
python-pkcs11(pypi、github、reference)提供了“PKCS#11 的高级 pythonic 实现”。整体上使用起来可能更容易,但可能缺乏兼容性和/或功能,具体取决于你想做什么,但我怀疑简单地检索证书可能没问题。
PyKCS11(pypi、github、reference)另一方面是原生 PKCS#11 库的包装器,它将延迟调用。这是一个较低级别的,但看起来更完整,而且如果相关的话,还可以提供使用您的特定供应商的实现的优势。
例如,我将使用 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])
我想说 Python 不会是使用安全棒进行 SSL 客户端身份验证的最佳选择。事实上,大多数 ssl 库都要求证书存在于磁盘上,这直接违背了使用安全棒的好处(有时是要求)。我很清楚这个答案并没有提供这个问题的完整解决方案,但希望能足够详细地揭示挑战,以便就是否进一步追求这个问题或寻找另一种方法做出有根据的决定。
无论如何,祝你好运。
关于python - 从 urllib2 或 httplib 访问需要 Safenet USB token 的页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36233685/
如有任何帮助,我将不胜感激。我使用 Python 3.4.1 并尝试导入 urllib.request 和 urllib.parse。没有成功。我总是收到: Traceback (most recen
我正在尝试一个教程代码,它从一个网站获取 html 代码并打印出来。我在 ubuntu 上使用 python 3.4.0。代码: import urllib.request page = urllib
根据这个answer几年前给出了一个相同的问题,Javascript 中的 encodeURIComponent(str) 应该等同于 Python 中的 urllib.quote(str, safe
1。弃用问题 在 Python 3.7 中,我使用 urllib.request.urlretrieve(..) 函数从 URL 下载了一个大文件。在文档 ( https://docs.python.
在 python 3 中,导入时出现此错误:没有名为“urllib.request.urlretrieve”的模块; “urllib.request”不是一个包 import urllib impor
import urllib print urllib.urlopen('http://www.reefgeek.com/equipment/Controllers_&_Monitors/Neptune
我在 gooogle colab 中使用来自 parselmouth 的 praat,在导入 from parselmouth.praat import call 时出现此错误 /usr/local/
是否有与 Python 的 urllib.parse.quote() 等效的 JavaScript 函数?和 urllib.parse.unquote() ? 我遇到的最接近的是encodeURI()
这个问题在这里已经有了答案: Importing installed package from script with the same name raises "AttributeError: m
Python 的 urllib.quote 和 urllib.unquote 在 Python 2.6.5 中无法正确处理 Unicode。这就是发生的事情: In [5]: print urllib
这个问题在这里已经有了答案: How to route urllib requests through the TOR network? [duplicate] (3 个回答) 关闭6年前。 示例代码
我正在制作一些简单的 python 帖子脚本,但效果不佳。 有两部分必须登录。 第一次登录使用' http://mybuddy.buddybuddy.co.kr/userinfo/UserInfo.a
我有以下脚本: from currency_converter import CurrencyConverter test = CurrencyConverter('http://www.ecb.eu
我正在编写一个小工具来监控学校的开课情况。 我编写了一个 python 脚本,每隔几分钟就会从每个部门获取当前类(class)的可用性。 该脚本一直正常运行,直到大学网站开始返回以下内容: SIS S
为什么下面的结果会出错? import re from urllib import quote as q s = re.compile(r'[^a-zA-Z0-9.: ^*$@!+_?-]') s.s
我正在开发一个网络爬虫来自动下载巴西网站上的一些文档。并且它使用了一些未知的编码(head 标签中没有定义字符集)。 人们只需付出很少的努力就可以阅读这些文档。但真正的问题是,列出文档的页面使用的链接
我有一个程序,我需要打开许多网页并下载其中的信息。然而,这些信息位于页面中间,需要很长时间才能找到。有没有办法让 urllib 只检索 x 行?或者,如果没有别的事,之后就不加载信息? 我在 Mac
我有一个脚本,使用 Urllib 打开我安装了谷歌分析的网页。我的问题是,为什么如果我执行脚本,GA 上不会显示访问次数? 最佳答案 Google Analytics 脚本是 JavaScript 代
我正在尝试下载航类搜索结果,但我不断收到一个与通过右键单击并手动存储网站获得的文件不同的文件。我已经尝试过 urllib 、 urllib2 以及我在这里找到的每个命令都无济于事。 这是一个 MWE:
我最近用Python(Windows 64位v3.3.1)编写了一个程序,并试图将其移植到D。我遇到的问题是我使用了urllib Python 中的模块,特别是 urllib.request.Requ
我是一名优秀的程序员,十分优秀!