使用带有请求的wincertstore(或将pfx转换为pem)会得到SSLError

时间:2018-01-22 21:15:58

标签: internet-explorer python-requests pem pfx

我尝试使用wincertstore将Internet Explorer(IE)证书传递给requests以下载文件。我的代码是:

import requests
import wincertstore

certfile = wincertstore.CertFile()
certfile.addstore('CA')
certfile.addstore('ROOT')
certfile.addstore('foocert_node0')
certfile.addstore('foocert_node1')
certfile.addstore('foocert_node2')

url = 'https://portal.foo.com/blahblahblah'
r = requests.get(url, verify=certfile.name)

我得到的错误是:

SSLError: ("bad handshake: Error([('SSL routines', 'ssl3_read_bytes', 'sslv3 alert handshake failure')],)",)

客户端(我认为是指我试图从url下载文件的网站,即foo.com)给了我一个包含3个节点的证书,这个节点已经加载到了IE中证书商店。不幸的是,客户端仅使用IE证书。

我不确定是否需要将我的客户端证书节点显式添加到certfile中,但不管怎样,我仍然会遇到同样的错误。

有趣的是,如果我只是将网址粘贴到IE窗口并点击返回,我会获得一个Windows安全/确认证书弹出窗口,一旦我接受,该文件就会下载。不幸的是,我尝试自动执行此过程(使用selenium),因此我想要一个适用于requests的解决方案。

我还尝试将客户端证书转换为pem,首先将Windows证书导出到pfx,然后使用以下代码:

import OpenSSL.crypto
import os
import requests
import ssl

def convertpfxtopem(certificate_pfx, password_pfx, certificate_pem):
    f_pem = open(certificate_pem, 'wb')
    pfx = open(certificate_pfx, 'rb').read()
    p12 = OpenSSL.crypto.load_pkcs12(pfx, str.encode(password_pfx))
    f_pem.write(OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, p12.get_privatekey()))
    f_pem.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, p12.get_certificate()))
    ca = p12.get_ca_certificates()
    if ca is not None:
        for cert in ca:
            f_pem.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert))
    f_pem.close()
    return Trueurlfile = 'test.xlsx'

convertpfxtopem(certificate_pfx, password_pfx, certificate_pem)
r = requests.get(url, verify=certificate_pem)

如果我使用此代码,我会得到相同的SSLError。

我错过了什么?非常感谢您的协助。

1 个答案:

答案 0 :(得分:0)

所以我正在寻找的解决方案比我意识到的要简单得多。原来curl已经使用了Windows证书库。所以从python / windows,这可以工作:

import subprocess
subprocess.call(['curl', '-O', '-J', url], cwd='Temp')

-O和-J标志在本地使用文件头中的名称保存文件,而cwd允许您将输出放在您选择的目录中(需要已经存在)。