SSL: CERTIFICATE_VERIFY_FAILED when connecting to a company Exchange Server

自古美人都是妖i 提交于 2019-12-07 08:09:28

I got it to work. I uninstalled pyopenssl and the error of my Example-Script changed to this:

requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)

Then I found some useful commands to get into the pem-file topic. Basically, I just had to add the certificate in order to solve my problem. Most people said that I have to add my certificate to a pem-file like cacert.pem, but it is possible that you have several modules installed that use different files. I found this topic very useful to find out the location of my cacert.pem file: LINK_1 e. g.:

python -c "import requests; print requests.certs.where()"

Next I had the problem, that I didn't have a certificate to add to the pem-file. Somehow my browser was able to send a https request, so the browser was able to use a certificate from windows. This link brought the solution.

import ssl

context = ssl.create_default_context()
der_certs = context.get_ca_certs(binary_form=True)
pem_certs = [ssl.DER_cert_to_PEM_cert(der) for der in der_certs]

with open('wincacerts.pem', 'w') as outfile:
    for pem in pem_certs:
        outfile.write(pem + '\n')

I exported the certificate from windows and added the file to my request-script:

import os
import requests

root_path = os.getcwd()
path_pem=os.path.join(root_path, 'wincacerts.pem')
requests.get('https://mail.ourserver.loc', verify=path_pem)

Back to my exchange script I added these lines to the beginning and added my certificate. I simply renamed the file from .pem to .crt. I was then able to send an email via the exchange server to myself.

root_path = os.getcwd()
path_pem=os.path.join(root_path, 'files', 'wincacerts.crt')

class RootCAAdapter(requests.adapters.HTTPAdapter):
    # An HTTP adapter that uses a custom root CA certificate at a hard coded location
    def cert_verify(self, conn, url, verify, cert):
        cert_file = {
            'mail.ourserver.loc': path_pem,
            'mail.internal': '/path/to/mail.internal.crt'
            }[urlparse(url).hostname]
        super(RootCAAdapter, self).cert_verify(conn=conn, url=url, verify=cert_file, cert=cert)

# Tell exchangelib to use this adapter class instead of the default
BaseProtocol.HTTP_ADAPTER_CLS = RootCAAdapter
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!