Итак, во-первых, у вас ни в коем случае не должно быть закрытого ключа! Как следует из названия, это частное sh соединение и не требуется. У вас может быть ключ publi c, но даже в этом нет необходимости, если вы используете стандартный SSL и доверяете центру сертификации, подписавшему сертификат сервера. Вы уверены, что это закрытый ключ? Файл начинается с -----BEGIN PRIVATE KEY-----
? Проверить с openssl rsa -noout -text -in server.key
. См. статью в Википедии и этот пост для получения дополнительной информации об асимметрии c криптографии.
Далее по пути: С помощью socket.bind()
вы привязываете сокет к порту на вашем локальном компьютере. Это невозможно, так как у вашего компьютера нет адреса (вы указываете адрес сервера). Судя по вашему коду, вы пытаетесь открыть сокет как сервер. Для этого вам понадобится закрытый ключ, но тогда вы будете принимать соединения, а не сами подключаться к другим машинам. У меня такое ощущение, что вы тут смешиваете две вещи. Обратитесь к python документации из socket.bind()
и к этому вопросу , поскольку он кажется тесно связанным. Также ознакомьтесь с документацией python по ssl . Я взял пример, который выполняет то, что вы просите из указанной документации:
import socket, ssl, pprint
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# require a certificate from the server
ssl_sock = ssl.wrap_socket(s,
ca_certs="/etc/ca_certs_file",
cert_reqs=ssl.CERT_REQUIRED)
ssl_sock.connect(('www.verisign.com', 443))
pprint.pprint(ssl_sock.getpeercert())
# note that closing the SSLSocket will also close the underlying socket
ssl_sock.close()
Также посмотрите пример о том, как открыть сокет SSL в режиме сервера .
Дальнейшие мысли: Вам действительно нужно делать все это самому? Если сервер, например, использует HTTPS (SSL-шифрованный HTTP), вы можете просто использовать библиотеку http.client .
Не стесняйтесь спрашивать, если вам нужно, чтобы я что-то уточнить. Я соответствующим образом обновлю свой ответ.
EDIT: Как вы указали, вы хотите открыть порт в режиме сервера, я сделал для вас пример (он сильно опирается на пример документации python):
import socket, ssl
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
context.load_cert_chain(certfile="cert.pem", keyfile="key.pem")
bindsocket = socket.socket()
bindsocket.bind(('127.0.0.1', 10023))
bindsocket.listen(5)
def deal_with_client(connstream):
data = connstream.recv(1024)
# empty data means the client is finished with us
while data:
print(data)
data = connstream.recv(1024)
while True:
newsocket, fromaddr = bindsocket.accept()
connstream = context.wrap_socket(newsocket, server_side=True)
try:
deal_with_client(connstream)
finally:
connstream.shutdown(socket.SHUT_RDWR)
connstream.close()
Запуск:
% python3 ssltest.py
b'hello server!\n'
b'this is data\n'
Клиентская сторона:
% openssl s_client -connect 127.0.0.1:10023
CONNECTED(00000005)
depth=0 C = SE, ST = Some-State, O = Internet Widgits Pty Ltd
verify error:num=18:self signed certificate
verify return:1
depth=0 C = SE, ST = Some-State, O = Internet Widgits Pty Ltd
verify return:1
---
Certificate chain
0 s:C = SE, ST = Some-State, O = Internet Widgits Pty Ltd
i:C = SE, ST = Some-State, O = Internet Widgits Pty Ltd
---
Server certificate
-----BEGIN CERTIFICATE-----
... certificate ...
-----END CERTIFICATE-----
subject=C = SE, ST = Some-State, O = Internet Widgits Pty Ltd
issuer=C = SE, ST = Some-State, O = Internet Widgits Pty Ltd
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 2272 bytes and written 404 bytes
Verification error: self signed certificate
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
... session stuff ...
Extended master secret: yes
---
hello server!
this is data
^C
Если вы используете какой-то обычный протокол, например HTTP, вам следует использовать библиотеку. Вот пример с flask:
>>> from flask import Flask
>>> app = Flask(__name__)
>>>
>>> @app.route("/")
... def hello():
... return "Hello World!"
...
>>> if __name__ == "__main__":
... app.run(ssl_context=('cert.pem', 'key.pem'))
...
* Serving Flask app "__main__" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on https://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [06/Aug/2020 11:45:50] "GET / HTTP/1.1" 200 -