先说一下我的环境,Python是2.7.13版本的,Python我用的话一直都用2.7版本的,没想到子版本里面也还有不同的地方。
接下来就说一说我这几天遇见的问题,Python ssl双向认证的问题;
建立ssl的安全socket链接,ssl这个介绍的网上一抓一大把,Python来写的也是一抓一大把(客户端的、服务端的),我就不多说了。
我只说几个需要注意的点:
(1)协议是一个坑,客户端和服务端的协议要对应,要不然会报错;
(2)证书一个坑,作为ssl来讲证书在里面扮演着一个很重要的角色,主要有这么几个证书:
CA证书(自签名的证书,也是根证书,是证书信任链的起点,用来颁发证书),它的作用就是负责校验对端传过来证书合法性的;
Server公钥证书,用来发给客户端表明身份的;
Server私钥证书,给自己用的,用来协商秘钥之类的。
Client公钥证书(非必要);
Client私钥证书(非必要)。
另外不同的开发环境证书的存储方式和编码格式也是不一样的,比如说java里面有一个用keytool生成的jks格式的证书库,Android里面有一个也是用keytool生成的叫做bks格式的证书库,这个网上也有很多资料我就不啰嗦了。
那么在Python里面它是要求要用PEM格式进行编码的后缀名无所谓(.crt/.cer/.pem/.gousheng都可以),但它的格式是这样的:
证书格式
Bag Attributes
friendlyName: CN=,OU=,O=,L=,ST=**,C=cn -storepass xxxx -keypass xxxx
localKeyID: … …
subject=/C=cn -storepass xxxx -keypass xxxx/ST=xxxx/L=xxxx/O=xxxx/OU=xxxx/CN=localhost
issuer=/C=cn -storepass xxxx -keypass xxxx/ST=xxxx/L=xxxx/O=xxxx/OU=xxxx/CN=localhost
—–BEGIN CERTIFICATE—–
… ….
—–END CERTIFICATE—–
key格式
Bag Attributes
friendlyName: *
localKeyID: … ….
Key Attributes:
—–BEGIN ENCRYPTED PRIVATE KEY—–
… …
—–END ENCRYPTED PRIVATE KEY—–
这两个是我从Android bks里面扒出来的,它主要的是在BEGIN和END之间的部分。
接下来我就说是怎么被坑的:
我的对端,也就是服务端是用java写的,它用的是keystore模式。
最开始我的代码是这样的:
mContext = ssl.SSLContext(ssl.PROTOCOL_TLSv1) #指定ssl版本,为tls1
mContext.verify_mode = ssl.CERT_REQUIRED #指定证书校验模式,需要交验
mContext.check_ho