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