[Twisted-Python] Re: How to make a secure connection between two computers
Noam Raphael
noamraph at gmail.com
Tue Feb 12 13:02:00 MST 2008
Thanks all!
I think that at the end, I'll just use Python's plain socket, since I
don't intend to serve more than one request at a time. I also don't
really need to use SSL, since my two computers can have a pre-shared
secret. Here's what I wrote - tell me what you think!
#!/usr/bin/env python
import sys
import socket
from Crypto.Hash import SHA
from Crypto.Cipher import ARC4
RANDOM_LEN = 16
def get_random():
return open('/dev/urandom').read(RANDOM_LEN)
def recv(sock, n):
buf = ''
while len(buf) < n:
r = sock.recv(n - len(buf))
if not r:
raise socket.error("Couldn't read enough bytes")
buf += r
return buf
def handshake(sock, secret):
my_random = get_random()
my_rc4 = ARC4.new(SHA.new(secret + my_random).digest())
sock.sendall(my_random)
peer_random = recv(sock, RANDOM_LEN)
peer_rc4 = ARC4.new(SHA.new(secret + peer_random).digest())
sock.sendall(peer_rc4.encrypt('\0'*RANDOM_LEN))
peer_response = recv(sock, RANDOM_LEN)
if my_rc4.decrypt(peer_response) != '\0' * RANDOM_LEN:
raise socket.error('Failed peer authentication')
return my_rc4, peer_rc4
def server(host, port, secret):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(1)
while True:
conn, addr = s.accept()
print 'Connected by', addr
conn.settimeout(1)
try:
my_rc4, peer_rc4 = handshake(conn, secret)
while True:
data = my_rc4.decrypt(conn.recv(1024))
if not data: break
print 'Received', repr(data)
conn.send(peer_rc4.encrypt(data))
conn.close()
except socket.error, e:
print 'Error:', e
else:
print 'Closed connection'
def client(host, port, secret):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(1)
s.connect((host, port))
my_rc4, peer_rc4 = handshake(s, secret)
s.send(peer_rc4.encrypt('Hello, world'))
data = my_rc4.decrypt(s.recv(1024))
s.close()
print 'Received', repr(data)
def main():
if len(sys.argv) != 5 or sys.argv[1] not in ('server', 'client'):
print "Usage: %s server/client host port secret"
return
is_server = sys.argv[1] == 'server'
host = sys.argv[2]
port = int(sys.argv[3])
secret = sys.argv[4]
if is_server:
server(host, port, secret)
else:
client(host, port, secret)
if __name__ == '__main__':
main()
More information about the Twisted-Python
mailing list