1.该文章从网上看了好多博客,并经过实践形成。环境为ubuntu12和ubuntu14
"========================================大纲提要和注意事项================================================================="
1.注意事项:
1)OpenSSL库中,各个函数的返回值的格式并不统一(有些用0表示失败,有些用0表示成功),请注意区分;
2)用在OpenSSL的fd不能设置为nonblock,否则在SSL_connect时会失败——感觉这一点限制了OpenSSL与除了libevent之外其他异步I/O库的适配
关于nonblock的问题,补充:可以在完成了SSL_connect/accept之后,将fd设置为nonblock
2.程序设计思想:
1)对程序来说,openssl将整个握手过程用一对函数体现,即客户端的SSL_connect和服务端的SSL_accept.而后的应用层数据交换则用SSL_read和 SSL_write来完成
Linux下基于OpenSSL的SSL安全通信设计
2)OpenSSL中的SSL安全通信可以分为两类,两类基本上的操作相同,一类是建立SSL环境后使用BIO读写,另一类是直接在socket上建立SSL上下文环境。
本文主要讨论在socket上建立SSL环境,以实现安全通信。首先需要生成一对客户机和服务器证书,这可以使用openssl的命令实现。
可以建立一个模拟的CA,生成数字证书。如下:
3.证书通俗的说:分为两类:(服务器的证书和秘钥); (客户端的证书和秘钥)。
一般情况下:不需要使用客户端的证书,(除非做银行、金融方面的加密业务,类似U盾。),它的作用是验证消息是该客户端发出的。
密码交互情况如下图:
"==========================================大纲提要和注意事项==============================================================="
"====================================自己试验过的,成功速度最快的==========================================="
1.最开始应该修改配置文件:一般我是修改/usr/local/ssl/openssl.cnf 这个配置文件;
2.设置环境变量,生成证书时访问这个配置文件:OPENSSL_CONF=/usr/local/ssl/openssl.cnf; export OPENSSL_CONF;
******************************************************
x509证书一般会用到三类文,key,csr,crt。
Key 是私用密钥openssl格,通常是rsa算法。
Csr 是证书请求文件,用于申请证书。在制作csr文件的时,必须使用自己的私钥来签署申,还可以设定一个密钥。
crt是CA认证后的证书文,(windows下面的,其实是crt),签署人用自己的key给你签署的凭证。
1.key的生成
openssl genrsa -des3 -out server.key 2048 (去掉中间的-des3可以生成不输密码的密钥)
这样是生成rsa私钥,des3算法,openssl格式,2048位强度。server.key是密钥文件名。为了生成这样的密钥,需要一个至少四位的密码。可以通过以下方法生成没有密码的key:
openssl rsa -in server.key -out server.key
server.key就是没有密码的版本了。
2. 生成CA的crt
openssl req -new -x509 -key server.key -out ca.crt -days 3650
生成的ca.crt文件是用来签署下面的server.csr文件。
3. csr的生成方法
openssl req -new -key server.key -out server.csr
需要依次输入国家,地区,组织,email。最重要的是有一个common name,可以写你的名字或者域名。如果为了https申请,这个必须和域名吻合,否则会引发浏览器警报。生成的csr文件交给CA签名后形成服务端自己的证书。
4. crt生成方法
CSR文件必须有CA的签名才可形成证书,可将此文件发送到verisign等地方由它验证,要交一大笔钱,何不自己做CA呢。
openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey server.key -CAcreateserial -out server.crt
输入key的密钥后,完成证书生成。-CA选项指明用于被签名的csr证书,-CAkey选项指明用于签名的密钥,-CAserial指明序列号文件,而-CAcreateserial指明文件不存在时自动生成。
最后生成了私用密钥:server.key和自己认证的SSL证书:server.crt
"====================================自己试验过的,成功速度最快的==========================================="
"====================================TCP流协议与ssl消息读写的异同==========================================="
1)SSL实现必须读取整条记录,哪怕select返回了一个字节可读,那么ssl也要读取整个记录,这种基于纪录的读写方式就是为了正确的加密个解密。因此
如果用select模型的话可能会出现一些莫名其妙的问题,
2)事实上也正是ssl消息需要加密解密从而需要整个消息整个消息读写才使得ssl协议的行为和tcp的有了少有的不一致。
tcp的特点是流式传输,流式的特点就是没有消息边界,一个连接就是一个流,需要应用程序自己去划分自己的数据,举个例子就是一端写入x字节,
对端可能读出y字节,具体多少要看网络状况和窗口情况,tcp在这一点上是相当复杂的,应用程序的发送只是简单的将数据放入tcp的发送缓冲区,
而接收只是简单的从接收缓冲区中取回数据,反观udp就不是这样子,udp是基于数据报的,就是说不能分段,一端写入多少另一端就读出多少,当
然也可能永远收不到,也可能乱序等等。现在看看ssl,它看起来好像是结合了tcp和udp的特点,它是有连接的,必须可靠传输并且按照顺序收发,
但是在SSL record层面却不是流式的(在API层面依然是流式的),每次调用SSL_read必须读入一个ssl纪录,一个ssl纪录有一个固定大小的头部(5字节),
该头部指示了消息类型,ssl版本号以及消息长度,首先需要读出一个ssl消息头部,接下来就要在该头部的消息长度字段的指导下进行消息体的读取,
而且必须读取完整个完整消息之后才能返回成功,否则均返回失败,并且什么都不做,ssl读操作中,带有头的消息是read的最小单位。ssl3_read_bytes
是openssl中SSL_read最终要调用的函数,它内部调用了ssl3_get_record:
"====================================TCP流协议与ssl消息读写的异同==========================================="