Twisted 安全信道

1、安装python的SSL插件pyOpenSSL

pip install pyopenssl

2、安装OpenSSL工具包

sudo apt-get install openssl

sudo apt-get install libssl-dev

OpenSSL命令:/usr/bin/openssl.

配置文件:usr/lib/ssl/*

加密信道的ssl通信

3、生成SSL密钥和证书

生成CA证书ca.crt,服务器密钥文件server.key,和服务器证书server.crt

# 生成CA密钥
openssl genrsa -out ca.key 2048


# 生成CA证书,本过程还会要求输入证书的所在地,公司等
openssl req -x509 -new -nodes -key ca.key -days 365 -out ca.crt


# 生成服务器证书RSA的密钥对
openssl genrsa -out server.key 2048


# 生成服务端证书CSR,本过程会要求输入证书所在地,公司等
openssl req -new -key server.key -out server.csr


# 生成服务器端证书 ca.crt
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365

上述命令生成服务器端证书时,必须在common nanme(CN)字段中如实输入站点访问地址,比如定义CN=www.mysite.com,如果通过ip访问就设ip地址

服务端的代码如下

from twisted.internet import ssl,reactor
from twisted.internet.protocol import Factory,Protocol

class EchoServer(Protocol):
    def dataReceived(self, data):
        self.transport.write(data)

if __name__ == '__main__':
    factory = Factory()
    factory.protocol = EchoServer
    reactor.listenSSL(8007,factory,ssl.DefaultOpenSSLContextFactory('../ssl/server.key','../ssl/server.crt')) # 配置密钥文件和证书文件路径
    reactor.run()

客户端方面:

from twisted.internet import ssl,reactor
from twisted.internet.protocol import ClientFactory


if __name__ == '__main__':
    factory = ClientFactory()
    reactor.connectSSL('192.168.1.10',8000,factory,ssl.ClientContextFactory())# SSL连接
    reactor.run()

这样TCP服务器和客户端就可以密文通信了

认证客户端身份的SSL通信

在应用中除了需要保证通信的私密性服务器还需要防止伪造的客户端与服务器通信,所以需要改造TCP客户端,

客户端身份通过客户端证书进行标识

from twisted.internet import ssl,reactor
from twisted.internet.protocol import ClientFactory

class MySSLContext(ssl.ClientContextFactory):
    def getContext(self):
        self.method = ssl.SSL.SSLv3_METHOD   #SSL协议版本
        ctx = ssl.ClientContextFactory.getContext(self)
        ctx.use_certificate_file('../ssl/client.crt') #客户端证书
        ctx.use_privatekey_file('../ssl/client.key') # 客户端密钥
        return ctx

if __name__ == '__main__':
    factory = ClientFactory()
    reactor.connectSSL('192.168.1.10',8000,factory,MySSLContext())# SSL连接
    reactor.run()

 服务器端需要根据客户端提交的证书验证是否允许其与自己通信

from twisted.internet import ssl,reactor
from twisted.internet.protocol import Factory,Protocol
from OpenSSL import SSL

class Echo(Protocol):
    def dataReceived(self, data):
        self.transport.write(data)
    

def verifyCallback(connection,x509,errnum,errdepth,ok):
    print("_verify(ok =%d):" % ok)  # CA是否匹配
    print('subject:',x509.get_subject()) # 客户端证书subject
    print('issuer:',x509.get_issuer()) # 客户端证书发行方
    print('errnum %s,errdepth %d' % (errnum,errdepth)) # 错误代码
    return True # 是否允许通信


if __name__ == '__main__':
    factory = Factory()
    factory.protocol = Echo
    myContextFactory = ssl.DefaultOpenSSLContextFactory('../ssl/server.key','../ssl/server.crt') # 服务器端的密钥和证书文件
    ctx = myContextFactory.getContext()
    ctx.set_verify(ssl.SSL.VERIFY_PEER | ssl.SSL.VERIFY_FAIL_IF_NO_PEER_CERT,verifyCallback) 
    ctx.load_verify_locations('../ssl/ca.crt') # 客户端证书的发行CA
    
    reactor.listenSSL(8007,factory,myContextFactory) # 配置密钥文件和证书文件路径
    reactor.run()

 

posted @ 2017-06-28 09:25  Erick-LONG  阅读(271)  评论(0编辑  收藏  举报