Я настраиваю проверку SSL-клиента в своем приложении Python. На данный момент мой код проверки концепции падает, просто устанавливая безопасное соединение.
Похоже, что сгенерированные мной сертификаты либо используют сертификат без необходимых разрешений (более вероятно, IMO), либо имеют разрешения, которые сервер не может понять или принять (чуть менее вероятно, IMO эм>).
Это должно быть относительно тривиально, но я не могу найти нужную документацию.
Я создал сертификат сервера и клиента через OpenSSL. Я делал это в прошлом для других приложений без каких-либо проблем. Но я гораздо меньше знаком с созданием клиентских сертификатов. OpenSSL сообщает, что сертификат клиента, который я использую, имеет расширения:
X509v3 extensions:
X509v3 Subject Key Identifier:
AF:AB:9D:AA:88:96:F4:0C:F5:56:9A:2C:DB:B6:BA:D9:DD:11:69:45
X509v3 Subject Alternative Name:
email:[email protected]
X509v3 Basic Constraints:
CA:FALSE
Netscape Cert Type:
SSL Client
X509v3 Authority Key Identifier:
keyid:E1:35:7C:39:7F:39:A4:43:D2:F8:00:59:38:91:71:AF:B9:38:AD:3F
X509v3 Key Usage:
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Client Authentication
Тривиальный тестовый код сервера:
import ssl
import socket
import logging
_log = logging.getLogger(__name__)
def main():
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain("1B.pem", "key2.pem")
context.verify_mode = ssl.CERT_REQUIRED
context.load_verify_locations("my_ca.crt")
raw_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
try:
# domain replaced for SO question
raw_server_socket.bind(('neptune.example.com', 8812))
raw_server_socket.listen(5)
server_socket = context.wrap_socket(raw_server_socket, server_side=True)
except Exception:
raw_server_socket.close()
raise
with server_socket:
while True:
try:
connection_to_client, address = server_socket.accept()
with connection_to_client:
connection_to_client.write(b'Hello')
except Exception as ex:
print(ex)
if __name__ == "__main__":
main()
Это дает ошибку:
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unsupported certificate purpose (_ssl.c:1076)
... Когда клиент подключился к этому:
import socket
import ssl
context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
context.load_cert_chain("1C.pem", "key.pem")
raw_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Domain changed for SO question
conn = context.wrap_socket(raw_socket, server_side=False, server_hostname="neptune.example.com")
conn.connect(("neptune.example.com", 8812))
conn.close()