SSL的通信与TCP相似,不同之处是首先先要生成证书。
openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout key.pem
服务器端程序为:
import socket, ssl, time
HOST = ''
PORT = 10023
BUFSIZE = 1024
ADDR = (HOST,PORT)
#socket create success
bindsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#socket bind success
bindsocket.bind(ADDR)
#socket listen success
bindsocket.listen(5)
def do_something(connstream, data):
return len(data)
def deal_with_client(connstream):
data = connstream.recv(BUFSIZE)
# empty data means the client is finished with us
while data:
backdata = do_something(connstream,data)
if not backdata:
# we'll assume do_something returns False
# when we're finished with client
break
connstream.send(str(backdata))
data = connstream.recv(BUFSIZE)
while True:
newsocket, fromaddr = bindsocket.accept()
print "socket accept one client from ",fromaddr
connstream = ssl.wrap_socket(newsocket, "key.pem", "cert.pem", server_side=True, ssl_version = ssl.PROTOCOL_TLSv1)
try:
deal_with_client(connstream)
finally:
connstream.shutdown(socket.SHUT_RDWR)
connstream.close()
客户端程序为:
import socket, ssl, pprint,time
HOST = '10.0.3.83'
PORT = 10023
BUFSIZE = 1024
ADDR = (HOST,PORT)
#socket create success
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# require a certificate from the server
ssl_sock = ssl.wrap_socket(s,ca_certs="cert.pem",cert_reqs=ssl.CERT_REQUIRED)
#socket connect success
ssl_sock.connect(ADDR)
# note that closing the SSLSocket will also close the underlying socket
pprint.pprint(ssl_sock.getpeercert())
while True:
data = raw_input('> ')
if not data:
break
ssl_sock.send(data)
data=ssl_sock.recv(BUFSIZE)
if not data:
break
print data
ssl_sock.close()
运行时首先启动服务器端,之后用客户端去连接,过程如下:
服务器端:
客户端:
交互过程中,首先将服务器端生成的证书复制到客户端程序的同路径下,随后运行程序,当客户端发送wangpeng时的数据包如下:
可见内容是杂乱的,起到了保护数据内容的作用。
作为对比,在普通的TCP客户端与服务器端对话的过程中,数据包如下。
可见是明文信息。
当证书有误时,会报错,如下:
服务器端:
客户端:
生成证书时,有两个文件,用文本编辑器打开,如下:
cert.pem
-----BEGIN CERTIFICATE-----
MIIDlTCCAn2gAwIBAgIJAPQtvkMnVSOsMA0GCSqGSIb3DQEBCwUAMGExCzAJBgNV
BAYTAndwMQswCQYDVQQIDAJ3cDELMAkGA1UEBwwCd3AxCzAJBgNVBAoMAndwMQsw
CQYDVQQLDAJ3cDELMAkGA1UEAwwCd3AxETAPBgkqhkiG9w0BCQEWAndwMB4XDTE1
MTAxMDAxNTY0MloXDTE2MTAwOTAxNTY0MlowYTELMAkGA1UEBhMCd3AxCzAJBgNV
BAgMAndwMQswCQYDVQQHDAJ3cDELMAkGA1UECgwCd3AxCzAJBgNVBAsMAndwMQsw
CQYDVQQDDAJ3cDERMA8GCSqGSIb3DQEJARYCd3AwggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQDvUQ5jIeIZaFXWYKR4AUIIyrbkMKj8Xcjvfy4KMB0qXy7V
YuP98Jy/hp5g/YzANq1G+a8p04P9F8HwFO3Z4jYYitqCKuXzos9zGILXarjwFTTA
eiI0Sc2xzYCkD4p8HYKSvwUbVWRYmI3+JIZQgQykT+07AMPbV8/y/rpZRi7OZdb5
XSBXwxvOGD+mZ4xBNurUjX4LXlQaQf4+uXpR9W/TI/6ZF6tl0F4QqnM8IWNO+bq6
PsLNdHWt9+0TjD/iB3offA5bdIqmlReBE5jXcka1g6lIPJfBUdlnylYRX8lvY/EV
YRQcG/IzNsPIsTdhUcDW/I2qMokz98uPG0d8ElYbAgMBAAGjUDBOMB0GA1UdDgQW
BBQ8XDm7KHptC2duHeWZCVslpSogvTAfBgNVHSMEGDAWgBQ8XDm7KHptC2duHeWZ
CVslpSogvTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQDRjGB98wwS
aPFIZ2NB2LqoQ95oOndSQQvJJPreJBnMJdgpo7D/C3A8CuuqoN8zP4SWhh4Z6yUj
YEGZ/wZDciUhy7wO9XIdFyv7V87EcUcH6XQqr8co2xz6Ss77mUWBI6SbNdwRdoOr
vM4MLYgl8G0aPIwUb5GZqaNYGs3jRjVNk9xaRLK9MT18noGG3+ULcf9eIgN28aIM
knqStE1w6cZrK8CaqX/8hIxi2031+apDibTsxQprRIJpVnCMjnUYR7xhWKVox7kf
8uSZAKbONspeGNrDhcqEszvRntNgiR9n4s9Hxa9VfSKWEQs9VodioI6p36aNp+th
5fmpo2/rr8wT
-----END CERTIFICATE-----
key.pem
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDvUQ5jIeIZaFXW
YKR4AUIIyrbkMKj8Xcjvfy4KMB0qXy7VYuP98Jy/hp5g/YzANq1G+a8p04P9F8Hw
FO3Z4jYYitqCKuXzos9zGILXarjwFTTAeiI0Sc2xzYCkD4p8HYKSvwUbVWRYmI3+
JIZQgQykT+07AMPbV8/y/rpZRi7OZdb5XSBXwxvOGD+mZ4xBNurUjX4LXlQaQf4+
uXpR9W/TI/6ZF6tl0F4QqnM8IWNO+bq6PsLNdHWt9+0TjD/iB3offA5bdIqmlReB
E5jXcka1g6lIPJfBUdlnylYRX8lvY/EVYRQcG/IzNsPIsTdhUcDW/I2qMokz98uP
G0d8ElYbAgMBAAECggEBALTFJXj8Py2yAiTNG28KhDbf6Qa1OvBmZ0GBb+WCMoWv
IFFPQaiv97c0mK3q2EbZBkp2kDmn7Cthpr0TEhdjKDmhqSxp+wjuEoV+HldZ5hhz
7ET3/J5CoX2NHX7PvmvCXr86S0E6X3IMyjUOoeZtlH8JYMkQ6uDkk8+ZWmnU+cYs
8Re5puhqYOJSTQ5bllPmjQKXSUde86Z6JroFFFBT603Q60PCwK3lz4uUv30DRIi1
k4qNNAbfIwQya5hgSWl2+a+Fwo+4+EFcCa/9rOC4MWEfQ+W+X3e7umQa98avBmyb
t2bDLiOrGnEt1kCgGAs+EuHNnbTtmrqR5fBYyHiumwECgYEA+9q/vTvRM1/Rdk5y
iCpyhB4CH72ql9wlsaAYpKKTGMbDbupXm7x1WzlricRCntPHJI8luV0aqXQzGQyy
zijTCh6Uu9zQzGhV8pob+GPb0tsvcDDumg2MHwaatHGerr2jD0xOAs4pUgm6WCi/
V+dJWV1tLUrR5j4wUzbvSxiK+i0CgYEA80F50NAQo7CzbanTZiOw3qPSoSo/GLf/
xKerL5irq8QUznVrzt9E2YvDkiroMSQE7t2mCNavTPP9gboBJotdS5BhBe5c4DI6
H2EN+6Ph0YzMK9OcZv/rMtngjW0/TIbh9SJMDPdvkvFYTpc5Zh689EzgoWTHpo7z
J5Pq0sM5JmcCgYBzkoxOUDbN9nhua81PAvuN+R9MZYL1MQbzHd5xHlGWGw/vxAXz
52WLOSxKCg/wRoqqEi5jg4AKptIT+qnKxR0jFal3E/uU8YQPUfzn3RsxBXgdabb0
ZqcYTbWMfF8vHMLI8GEUFHsNtH0Ym4pC0lXsdlz1XdI4b+1JInpo4ZhU+QKBgQCP
kOorMlFPup77LwrEMnZVwEw0sDFTDm1WjDp9Oda/5lb9TtHU43LIDjPblZU6Q27h
51Dx0HrfqPTKVpQNQp1KVqjcjkSkUSB6mpZdGOjS+w0ZJKgfJhWTCoH8FikQql67
hYVq9bIVAHnE0H2g5q1QZfsBZfBrPd0GU8d4op2dKwKBgG1SQM06q+4jiXzypyok
wcFfk35X2sCuXjxmnKMC24a8BOg3sAK/qg7GF+Q2nUD0FrW/xZ2HD7sQ4+3zLqcz
Ai5aJMer2n28Qn1S0T9cPeO+o5YWNCe+vKbZHuxtLJMCAvf9cGPYCKg19pKVY6cT
AAiCY3adHJHDjU2LxfaG2vr+
-----END PRIVATE KEY-----
完事儿。。。