So, first of all, you should absolutely not have the private key! As the name says, it is private and not necessary to establish a connection.
You could have the public key, but even that is not necessary as long as you use standard SSL and you trust the CA that signed the servers certificate.
Are you sure, it is the private key? Does the file begin with -----BEGIN PRIVATE KEY-----? Check with openssl rsa -noout -text -in server.key.
Refer to the wikipedia article and this post for more on asymmetric cryptography.

Further along the way:
With socket.bind() you bind a socket to a port on your local machine. This is not possible, as your machine does not have the address (you provide a server address).
From your code, it looks like you are trying to open the socket as a server. You will need the private key for that, but then you will be accepting connections and not connect to other machines yourself. I have a feeling, that you are mixing up two things here.
Refer to the python documentation of socket.bind() and to this question as this seems to be closely related.
Also check out the python documentation on ssl. I took the example, that does what you are asking for from said documentation:

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()

Also have a look on the example on how to open a SSL socket in server mode.

Further thoughts:
Do you really need to do all that TLS stuff yourself? If the server, for example, uses HTTPS (SSL encrypted HTTP), you can just use the http.client library.

Feel free to ask, if you need me to clarify something. I'll update my answer accordingly.

EDIT:
As you indicated, you want to open a port in server mode, I made an example for you (it heavily leans on the python documentation example):

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()

Running it:

% python3 ssltest.py
b'hello server!\n'
b'this is data\n'

The client side:

% 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

If you use some usual protocol like HTTP, you should use a library though. Here is a example with 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 -
Answer from toydarian on Stack Overflow
🌐
Python
docs.python.org › 3 › library › ssl.html
ssl — TLS/SSL wrapper for socket objects — Python 3.14.4 ...
This mode is not sufficient to verify a certificate in client mode as it does not match hostnames. check_hostname must be enabled as well to verify the authenticity of a cert. PROTOCOL_TLS_CLIENT uses CERT_REQUIRED and enables check_hostname by default. With server socket, this mode provides mandatory TLS client cert authentication.
Top answer
1 of 1
15

So, first of all, you should absolutely not have the private key! As the name says, it is private and not necessary to establish a connection.
You could have the public key, but even that is not necessary as long as you use standard SSL and you trust the CA that signed the servers certificate.
Are you sure, it is the private key? Does the file begin with -----BEGIN PRIVATE KEY-----? Check with openssl rsa -noout -text -in server.key.
Refer to the wikipedia article and this post for more on asymmetric cryptography.

Further along the way:
With socket.bind() you bind a socket to a port on your local machine. This is not possible, as your machine does not have the address (you provide a server address).
From your code, it looks like you are trying to open the socket as a server. You will need the private key for that, but then you will be accepting connections and not connect to other machines yourself. I have a feeling, that you are mixing up two things here.
Refer to the python documentation of socket.bind() and to this question as this seems to be closely related.
Also check out the python documentation on ssl. I took the example, that does what you are asking for from said documentation:

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()

Also have a look on the example on how to open a SSL socket in server mode.

Further thoughts:
Do you really need to do all that TLS stuff yourself? If the server, for example, uses HTTPS (SSL encrypted HTTP), you can just use the http.client library.

Feel free to ask, if you need me to clarify something. I'll update my answer accordingly.

EDIT:
As you indicated, you want to open a port in server mode, I made an example for you (it heavily leans on the python documentation example):

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()

Running it:

% python3 ssltest.py
b'hello server!\n'
b'this is data\n'

The client side:

% 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

If you use some usual protocol like HTTP, you should use a library though. Here is a example with 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 -
🌐
GitHub
gist.github.com › oborichkin › d8d0c7823fd6db3abeb25f69352a5299
Simple TLS client and server on python · GitHub
CA/sub-ca: openssl ca -config sub-ca.conf -extensions server_cert -days 1825 -notext -in ../server/csr/server.csr -out ../server/certs/server.crt # (Optional) Create Certificate Chain CA/server/certs: type server.crt ..\..\sub-ca\certs\sub-ca.crt > chained.crt ... Welcome Sorry, I'm new to Python and security. Is it possible to make a connection without this file because, frankly, I didn't understand how to create it despite reading about the topic? ... You have to understand what make connection secure. If client and server would communicate in plain text then anyone could see what is going in the connection and make date change on it's way.
🌐
GitHub
github.com › arthurazs › python-tls
GitHub - arthurazs/python-tls: Simple TLS connection example · GitHub
Warning If you change the CN value, ... address. Open the terminal and enter the following commands: user@pc:~$ cd python-tls user@pc:~/python-tls$ python3 server.py...
Starred by 14 users
Forked by 14 users
Languages   Python
🌐
Praneeth's Blog
praneethwifi.in › 2023 › 05 › 16 › tls1-3-data-communication-b-w-client-server-using-python-sockets
TLS1.3 Data Communication b/w Client & Server using python sockets – Praneeth's Blog
May 16, 2023 - Now run the client program as python3.8 client.py, and observe the below output on server and client. Figure 3 : Server Received the Data “Hi, Praneeth Here …” · Figure 4 : Client Received the data “Server –> Hi Praneeth, How are you doing ?” from server · Observe the below capture when this communication happened b/w client and server. We can observe that TLS1.3 handshake has happened between client and server and also observe that data is being sent in TLS1.3 tunnels b/w client and server and the data is encrypted.
🌐
PyPI
pypi.org › project › tls-client
tls-client · PyPI
--add-binary '{path_to_library}/tls_client/dependencies/tls-client-arm64.dylib:tls_client/dependencies'
      » pip install tls-client
    
Published   Feb 02, 2024
Version   1.0.1
🌐
Python
peps.python.org › pep-0748
PEP 748 – A Unified TLS API for Python | peps.python.org
June 27, 2024 - They can be thought of as factories for TLSSocket and TLSBuffer objects. Unlike the current ssl module, we provide two context classes instead of one. Specifically, we provide the ClientContext and ServerContext classes. This simplifies the APIs (for example, there is no sense in the server providing the server_hostname parameter to wrap_socket(), but because there is only one context class that parameter is still available), and ensures that implementations know as early as possible which side of a TLS connection they will serve.
🌐
Electricmonk
electricmonk.nl › log › 2018 › 06 › 02 › ssl-tls-client-certificate-verification-with-python-v3-4-sslcontext
SSL/TLS client certificate verification with Python v3.4+ SSLContext | Electricmonk.nl weblog
June 2, 2018 - Normally you’d use a server certificate from a Certificate Authority such as Let’s Encrypt, and would setup your own Certificate Authority so you can sign and revoke client certificates. ... Make sure to enter ‘example.com’ for the Common Name. ... The Common Name for the client certificate doesn’t really matter. ... #!/usr/bin/python3 import socket import ssl host_addr = '127.0.0.1' host_port = 8082 server_sni_hostname = 'example.com' server_cert = 'server.crt' client_cert = 'client.crt' client_key = 'client.key' context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile=server_cert) context.load_cert_chain(certfile=client_cert, keyfile=client_key) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) conn = context.wrap_socket(s, server_side=False, server_hostname=server_sni_hostname) conn.connect((host_addr, host_port)) print("SSL established.
Find elsewhere
🌐
Medium
medium.com › @notrohan › tls-using-js-and-python-a-native-implementation-of-https-in-client-server-architecture-db6002bfc57d
TLS using JS and Python — A native implementation of HTTPS in Client-Server Architecture | by Rohan Sharma | Medium
May 4, 2020 - At Client Side, we will use Forge.js to perform RSA Encryption on our payload. ... Initialise forge using public key (variable ‘pem_file’ from public.js) and apply encryption on payload — reqBody: ... At Server Side, we will use Pycrypto module in our flask to Decrypt the payload received.
🌐
Snyk
snyk.io › blog › implementing-tls-ssl-python
Implementing TLS/SSL in Python | Snyk
October 16, 2022 - Now that we have successfully generated ... encryption throughout its communication with a client. The Python program below starts up an HTTPS server on your localhost at port 443....
🌐
A Security Site
asecuritysite.com › subjects › chapter107
Client/server with SSL
Next we will create a server which will listen on Port 443, and support two cipher suites ('AES256+ECDH:AES256+EDH'): · Now we will create the client to connect on Port 443. As we have a self-signed certificate, we will disable the checking of the host and certificate (remember to change the ...
🌐
Stack Overflow
stackoverflow.com › questions › 42915476 › client-server-tls-in-python
ssl - Client/Server TLS in Python - Stack Overflow
File "C:\Users\PC\AppData\Local\Programs\Python\Python35\lib\asyncio\tasks.py", line 288, in _wakeup value = future.result() File "C:\Users\PC\AppData\Local\Programs\Python\Python35\lib\asyncio\futures.py", line 274, in result raise self._exception File "C:\Users\PC\AppData\Local\Programs\Python\Python35\lib\asyncio\events.py", line 125, in _run self._callback(*self._args) File "C:\Users\PC\AppData\Local\Programs\Python\Python35\lib\asyncio\selector_events.py", line 667, in _read_ready self._protocol.data_received(data) File "C:\Users\PC\AppData\Local\Programs\Python\Python35\lib\asyncio\sslpr
🌐
Pythontic
pythontic.com › ssl › sslsocket › introduction
The SSLSocket class in Python | Pythontic.com
The SSLSocket is supplied with the CA Certificate, the certificate of the server and the corresponding private key. A call to the getpeercert() on the secure client connection(ie., the SSLSocket instance) gets the certificate of the client.
🌐
LabEx
labex.io › tutorials › python-how-to-secure-client-server-communication-in-python-398063
How to secure client-server communication in Python | LabEx
Python's built-in ssl module provides a straightforward way to implement SSL/TLS encryption for client-server communication. Here's an example of a simple SSL/TLS-enabled server and client:
🌐
Python.org
discuss.python.org › python help
Handshake ( Server Hello ) - Python Help - Discussions on Python.org
May 25, 2023 - Do I need to send a ( Server Hello ) as a response to the handshake ( Client Hello ) received, but I couldn’t find out why it doesn’t work? If I can help, below is an example: import socket import ssl # Create a TCP/IP socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Bind the socket to port 443 sock.bind(("localhost", 443)) # Listen for connections sock.listen(1) # Accept a connection conn, addr = sock.accept() # Create a SSL/TLS context ctx = ssl.SSLContext() # Load the ...
🌐
Readthedocs
wolfcrypt.readthedocs.io › en › latest › examples.html
Client and Server Examples — wolfssl Python 0.1.0 documentation
import socket import wolfssl CA_DATA = \ """ -----BEGIN CERTIFICATE----- MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm +9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW PNt0OKR
🌐
GitHub
github.com › xliu59 › SSL-TLS_SOCKET
GitHub - xliu59/SSL-TLS_SOCKET: A basic implementation on SSL/TLS socket on both server and client
python server.py --sslv23 --cacert ./ssl/certificate.pem --cipher ECDHE-RSA-AES256-GCM-SHA384 127.0.0.1 8801 index.html · Note: For the purpose of testing only the connection, on the client-side should not specify certificate file path (but DOES NOT mean this parameter won’t work, its effectiveness can be tested in the next part), otherwise will change to the result of certificate-printing (next part).
Starred by 13 users
Forked by 4 users
Languages   Python 99.1% | HTML 0.9% | Python 99.1% | HTML 0.9%
🌐
Faircom
docs.faircom.com › docs › en › UUID-cb67a0f7-170b-352a-39eb-3307a423b7d4.html
TLS in Python for MQTT
Receiving the message means your client was able to subscribe and publish to your broker using TLS for encryption and authentication. ... import time import paho.mqtt.client as mqtt # If this fails, do "pip install paho-mqtt" import ssl use_client_certificate = True # Change to False to log in to MQTT broker using a client username/password. ca_certificate_file = "ca.crt" # File that holds the CA certificate which signed the server certificate used by the broker and the client certificate used by this script.
🌐
PyMongo
pymongo.readthedocs.io › docs home › client libraries › python › security
Configure Transport Layer Security (TLS) - PyMongo Driver - MongoDB Docs
The following code example shows how to install the certifi module from PyPi and export the SSL_CERT_FILE environment variable: An error message similar to the following means that the OpenSSL version used by Python doesn't support a new enough TLS protocol to connect to the server:
🌐
Example Code
example-code.com › chilkat2-python › socket.asp
Socket/SSL/TLS Examples for Chilkat2-Python
Chilkat • HOME • Android™ • AutoIt • C • C# • C++ • Chilkat2-Python • CkPython • Classic ASP • DataFlex • Delphi DLL • Go • Java • Node.js • Objective-C • PHP Extension • Perl • PowerBuilder • PowerShell • PureBasic • Ruby • SQL Server • Swift • Tcl • Unicode C • Unicode C++ • VB.NET • VBScript • Visual Basic 6.0 • Visual FoxPro • Xojo Plugin