Запросы Python отправляют сертификат как строку

Я не могу заставить рукопожатие работать правильно.

cert = 'path/to/cert_file.pem'
url = 'https://example.com/api'

requests.get(url, cert=cert, verify=True)

Это нормально, когда я использую его локально, где у меня есть файл физически. Мы размещаем наше приложение на геройку и используем environmentvariables.

Модуль запросов, похоже, не принимает сертификаты в виде строк. например.

$ export CERTIFICATE="long-list-of-characters"

requests.get(url, cert=get_env('CERTIFICATE'), verify=True)

Я также пробовал что-то вроде этого:

cert = tempfile.NamedTemporaryFile()
cert.write(CERTIFICATE)
cert.seek(0)
requests.get(url, cert=cert.name, verify=True)

Прежде всего, он работает локально, но не на героку. В любом случае, это не похоже на прочное решение. Я получаю сообщение об отсутствии связи SSL.

Любые предложения?

Ответ 1

Согласно документации requests:

Закрытый ключ вашего локального сертификата должен быть незашифрованным. В настоящее время запросы не поддерживают использование зашифрованных ключей.

Вы также можете указать локальный сертификат для использования в качестве сертификата на стороне клиента, как один файл (содержащий закрытый ключ и сертификат) или как кортеж обоих путей к файлу:

requests.get('https://kennethreitz.com', cert=('/path/client.cert', '/path/client.key'))

Вы должны указать путь для открытого и закрытого ключа... или вы можете указать путь к одному файлу, который содержит оба.

Ответ 2

Ответ Василия технически правильный, хотя сам по себе он не отвечает на ваш вопрос. Ключевой файл, действительно, должен быть незашифрованным для начала.

Я сам только что решил такую ​​ситуацию, как ваша. Вы были на правильном пути; все, что вам нужно было сделать, было

1. Передать delete=False в NamedTemporaryFile(), чтобы файл не удалялся после вызова close()

2. close() файл temp перед его использованием, поэтому он будет сохранен

Обратите внимание, что это очень опасная вещь. delete=False, как я понимаю, заставляет файл оставаться на диске даже после удаления ссылки на него. Итак, чтобы удалить файл, вы должны вручную вызвать os.unlink(tmpfile.name).

Выполнение этого с помощью сертификатов представляет собой огромный риск для безопасности: вы должны гарантировать, что строка с сертификатом защищена и скрыта, и никто не имеет доступа к серверу.

Тем не менее, это довольно полезная практика в случае, например, управления вашим приложением как на сервере Heroku в качестве тестовой среды, так и в изображении Docker, встроенном в облако, где директивы COPY не являются опцией. Это также определенно лучше, чем сохранение файла в репозитории git: D