43 lines
		
	
	
	
		
			1.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			43 lines
		
	
	
	
		
			1.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import socket
 | 
						|
from typing import Tuple
 | 
						|
 | 
						|
from Crypto.PublicKey import RSA
 | 
						|
from Crypto.Cipher import PKCS1_OAEP
 | 
						|
 | 
						|
 | 
						|
def generate_rsa(bits: int = 2048) -> Tuple[RSA.RsaKey, RSA.RsaKey]:
 | 
						|
    key = RSA.generate(bits)
 | 
						|
    return key.publickey(), key
 | 
						|
 | 
						|
 | 
						|
def main() -> None:
 | 
						|
    host = "127.0.0.1"
 | 
						|
    port = 5003
 | 
						|
 | 
						|
    pub, priv = generate_rsa(2048)
 | 
						|
    pub_pem = pub.export_key()
 | 
						|
 | 
						|
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as srv:
 | 
						|
        srv.bind((host, port))
 | 
						|
        srv.listen(1)
 | 
						|
        conn, _ = srv.accept()
 | 
						|
        with conn:
 | 
						|
            # Send server public key
 | 
						|
            conn.sendall(len(pub_pem).to_bytes(4, "big") + pub_pem)
 | 
						|
 | 
						|
            # Receive client's encrypted message
 | 
						|
            clen = int.from_bytes(conn.recv(4), "big")
 | 
						|
            ctext = conn.recv(clen)
 | 
						|
 | 
						|
            cipher = PKCS1_OAEP.new(priv)
 | 
						|
            msg = cipher.decrypt(ctext)
 | 
						|
            # Respond: encrypt reply with same public (client will not be able to decrypt without its private),
 | 
						|
            # so just echo plaintext length as acknowledgement for demo.
 | 
						|
            reply = f"received:{len(msg)}".encode()
 | 
						|
            conn.sendall(len(reply).to_bytes(4, "big") + reply)
 | 
						|
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    main()
 | 
						|
 | 
						|
 |