openssl一二事
由于工作上的需要,最近两天折腾openssl来实现一些信令加密解密的事情。总体来说,openssl是个很不错的库,也是个很不错的工具。使用openssl做tls客户端编程没有太大问题,而实现tls服务器端则有些地方需要注意。
首先要注意的一点就是:在握手之前(SSL_accept),绝对不能采用非阻塞方式。握手成功之后,才可以将socket修改为非阻塞方式,否则握手不会成功,服务器总是会向客户端返回“Engypted alert”消息并结束握手。
如果是在windows环境生成证书和密钥,建议使用SimpleCA工具,很好用。同时要注意:(1)客户端应安装或者使用该工具生成的根证书,例如ca.crt。(2)服务端需要使用生成的服务端证书和密钥,即.crt和.key文件。(3)生成证书时(无论是根证书还是服务端证书),Common Name都必须要设置为当前服务器的IP地址或者主机名,否则双方握手时,可能产生”certificate name mismatch”等错误。(4)如果需要将证书导入windows系统,必须导入为“受信任的根证书颁发机构”类型。
如果是Ubuntu等linux系统,可以直接安装使用openssl生成证书,如以下命令:
生成根证书: openssl genrsa -out ca.key 4096 openssl req -new -x509 -days 3650 -key ca.key -out ca.crt 生成服务端证书和密钥 openssl genrsa -out server.key 1024 openssl req -new -key server.key -out server.csr openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
理论上来说,可以将.crt和.key文件合并在一起,设置为.pem文件。不过实践证明,openssl的API是要求SSL_CTX_use_PrivateKey_file函数来加载密钥文件的,否则握手还是会出问题(当然,也可能是需要另外单独的设置)。