首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从urllib2 ot httplib访问需要安全USB令牌的页面

从urllib2 ot httplib访问需要安全USB令牌的页面
EN

Stack Overflow用户
提问于 2016-03-26 09:29:27
回答 1查看 1.6K关注 0票数 7

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

代码语言:javascript
复制
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令牌做同样的操作?

EN

回答 1

Stack Overflow用户

发布于 2018-02-21 12:30:38

TL;博士在中做这件事有很大的注意事项和安全问题。有效的“解决方案”包括使用PKCS#11库从密钥读取证书,然后以某种方式将证书持久化到磁盘上,最后将生成的文件路径传递给请求对象。 每根警棍的特殊性也会有所不同。有些make不提供将证书连同其私钥(也称为.pfx或.p12文件)一起存储,这将使此解决方案根本行不通。我没有安全手杖,所以用我自己的,请记住这一点。

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

1. Python中具有HTTPS功能的库

您对使用httplib (http.client for python3.x)或urllib的需求引入了一个很大的警告,即请求中使用的证书必须是磁盘上的文件(对于在其顶部构建的所有库(例如requests)也是如此)。请参阅cnelson关于如何使用存储在python中字符串变量中的证书打开ssl套接字的答案的原因(简而言之:这是因为python的ssl库使用了本机C库,该库不提供将内存中的对象作为证书传递)。还请参阅迪玛·蒂斯尼克( Dima Tisnek )的下一个答案详细说明可能的解决办法与不同程度的黑客技术。

如果在磁盘上写入证书(即使是暂时的)对您来说是不可能的,因为它很可能是因为您使用了一根安全棒,那么它开始看起来不太好。

2.从保安棍取得证书

您面临的最大挑战是获取证书,该证书目前位于安全棒内。与其他许多公司一样,Safenet是PKCS#11支持的SmartCard的核心。我建议您熟悉这些概念,但从本质上讲,SmartCard是一个标准化的芯片设计,而PKCS#11是一个与其接口的标准化协议。当然,“标准化”附带了一些警告,因为许多供应商都有自己的实现,但是它可能已经足够标准化了。这里的诀窍是使用棒上可用的PKCS#11接口来提取证书的属性。这就是web浏览器在使用存储的证书在网站上进行身份验证时所做的事情,所以您需要让python程序做类似的事情。

2.1选择PKCS#11库

不幸的是,在搜索"python pkcs11“时,只有少数库出现。我对其中任何一个都没有既得利益,而且可能还有其他不那么显赫的利益。

python-pkcs11 (皮皮github参考文献)提供了一个“PKCS#11的高水平的、仿生的实现”。它可能更容易使用,但可能缺乏兼容性和/或特性,这取决于您想要做什么,但我想,简单地检索证书可能是可以的。

另一方面,PyKCS11 (皮皮github参考文献)是本机PKCS#11库的包装器,它将把调用推迟到该库。这是一个较低的层次,但看起来更完整,加上可能有优势提供使用您的特定供应商的实现,如果有关。

2.2示例代码

例如,我将使用python 11的更友好的用户API。请记住,这段代码没有经过彻底的测试(并且已经进行了部分简化),可以用来说明一般的想法。

代码语言:javascript
复制
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库都要求证书存在于磁盘上,这一事实直接违背了使用安全棒的好处(有时甚至是要求)。我很清楚,这个答案并没有为这个问题提供一个完整的解决方案,但我希望能够充分详细地揭示这些挑战,以便就是进一步研究这一问题还是寻找另一种方式作出明智的决定。

不管怎样,祝你好运。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36233685

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档