Как убрать ошибку "CA signature digest algorithm too weak (_ssl.c:997)" при обращении к внешнему API
Работаю в Ubuntu 22, на Python 3.10. Делаю запросы в Песочницу API МДЛП Честный знак: https://api.sb.mdlp.crpt.ru
ГОСТ-шифры настроил, сервер принимает. Но Serever Hello приходит с сертификатом "CRYPTO-PRO Test Center 2", который почему-то не верифицируется. В документации API МДЛП в настройках для соединения с Песочницей дана ссылка на "тестовый корневой сертификат от КриптоПРро": Ссылка из документации API
Скачал корневой серт в формате base64, в коде указываю путь на него (session.verify = './certs/certnew.cer'):
import json
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.ssl_ import create_urllib3_context
CIPHERS = 'GOST2012-GOST8912-GOST8912'
BASE_URL = 'https://api.sb.mdlp.crpt.ru/api/v1/'
URL_CODE = BASE_URL + 'auth'
class GOSTAdapter(HTTPAdapter):
def init_poolmanager(self, *args, **kwargs):
context = create_urllib3_context(ciphers=CIPHERS)
kwargs['ssl_context'] = context
return super(GOSTAdapter, self).init_poolmanager(*args, **kwargs)
def proxy_manager_for(self, *args, **kwargs):
context = create_urllib3_context(ciphers=CIPHERS)
kwargs['ssl_context'] = context
return super(GOSTAdapter, self).proxy_manager_for(*args, **kwargs)
session = requests.Session()
session.mount('https://api.sb.mdlp.crpt.ru', GOSTAdapter())
session.verify = './certs/certnew.cer' # Если указать False - запрос проходит, данные поступают.
headers = {'Content-Type': 'application/json;charset=UTF-8'}
data = {
'client_id': '***',
'client_secret': '***',
'user_id': '***',
'auth_type': 'SIGNED_CODE'
}
response = session.post(URL_CODE, data=json.dumps(data), headers=headers)
print('code: ', response.json()['code'])
Но выходит ошибка:
requests.exceptions.SSLError: HTTPSConnectionPool(host='api.sb.mdlp.crpt.ru', port=443): Max retries exceeded with url: /api/v1/auth (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: CA signature digest algorithm too weak (_ssl.c:997)')))
То есть алгоритм дайджеста подписи CA слишком слаб. Без проверки сертификата сервера (verify=False) запрос проходит, данные поступают, но надо сделать с проверкой.
Итак, это данные корневого сертификата, который скачан по ссылке из документации API:
Signature Algorithm: GOST R 34.11-94 with GOST R 34.10-2001
Issuer: emailAddress = support@cryptopro.ru, C = RU, L = Moscow, O = CRYPTO-PRO LLC, CN = CRYPTO-PRO Test Center 2
Validity
Not Before: May 27 07:24:26 2019 GMT
Not After : May 26 07:34:05 2024 GMT
А это данные сертификата сервера:
Certificate chain
0 s:CN = api.sb.mdlp.crpt.ru
i:emailAddress = support@cryptopro.ru, C = RU, L = Moscow, O = CRYPTO-PRO LLC, CN = CRYPTO-PRO Test Center 2
a:PKEY: gost2012_512, 512 (bit); sigalg: id-GostR3411-94-with-GostR3410-2001
v:NotBefore: Dec 5 12:00:16 2022 GMT; NotAfter: Mar 5 12:10:16 2023 GMT
Судя по данным сертификатов, верификация должна проходить. По крайней мере, на алгоритм не должен ругаться, ибо они совпадают. Я не понимаю, почему не проходит верификация.
Есть версия, что настройки Openssl не позволяют использовать такие старые ("слабые") алгоритмы, попробовал в конфиге openssl.cnf поставить значение CipherString = DEFAULT:@SECLEVEL=0. Это не дало никакого эффекта. Возможно, в системе нужно ещё что-то сделать, и я об этом не знаю.
Как настроить системный OpenSSL 3.0, чтобы он не ругался на старые ("слабые") алгоритмы? Поможет ли в этом как-нибудь pyopenssl (я им никогда не пользовался)?