1. OpenSSL
1.1 OpenSSL简介
SSL,Security Socket Layer,是一个安全传输协议,在Internet网上进行数据保护和身份确认。OpenSSL是一个开放源代码的实现了SSL及相关加密技术的软件包,由加拿大的Eric Yang等发起编写的。OpenSSL的官方网站为http://www.openssl.org/,源代码可以从ftp://ftp.openssl.org/source/上下载,也可以从OpenSSL的镜像网站下载。
OpenSSL主要包括三个组件:openssl-多用途命令行工具;libcrypto-加密算法库;libssl-加密模块应用,主要实现TLS/SSL。
OpenSSL采用C语言作为开发语言,这使得OpenSSL具有优秀的跨平台性能,这对于广大技术人员来说是一件非常美妙的事情,可以在不同的平台使用同样熟悉的东西。OpenSSL支持Linux、Windows、BSD、Mac、VMS等平台,这使得OpenSSL具有广泛的适用性。但习惯C语言总比使用C++重新写一个跟OpenSSL相同功能的软件包轻松不少。
Openss的功能主要分为基本功能和辅助功能:基本功能,OpenSSL整个软件包大概可以分成三个主要的功能部分:密码算法库、SSL协议库以及应用程序。OpenSSL的目录结构自然也是围绕这三个功能部分进行规划的。作为一个基于密码学的安全开发包,OpenSSL提供的功能相当强大和全面,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,并提供了丰富的应用程序供测试或其它目的使用。辅助功能,
BIO机制是OpenSSL提供的一种高层IO接口,该接口封装了几乎所有类型的IO接口,如内存访问、文件访问以及Socket等。这使得代码的重用性大幅度提高,OpenSSL提供API的复杂性也降低了很多。OpenSSL对于随机数的生成和管理也提供了一整套的解决方法和支持API函数。随机数的好坏是决定一个密钥是否安全的重要前提。OpenSSL还提供了其它的一些辅助功能,如从口令生成密钥的API,证书签发和管理中的配置文件机制等等。
1.2 OpenSSL的几个主要版本
OpenSSL 0.9.8(2005年)
- 新增支持sha256算法
- 新增支持DTLS
- 新增支持Win64系统
- 新增支持RSA X.931等
- 其他新增优化项
OpenSSL 1.0.2(2015)
- 新增支持DTLS1.2和TLS1.2
- 新增支持RSA-PSS, RSA-OAEP, ECDH and X9.42 DH等算法
- 其他新增、优化项
- will be supported until 2019-12-31.
OpenSSL 1.1.0 (2016)
- 新增ClientHello回调函数
- 删除MIPS o32 ABI on IRIX的支持
- 新增对HKDF的支持
- 新增支持blake2b 和 blake2s
- 其他hug修复和优化
- will be supported until 2019-09-11.
OpenSSL 1.1.1(2018)
- 2018年9月发布,新版本支持TLS1.3协议
- 新增SM2算法支持
- 其他bug修改和优化
- will be supported until 2023-09-11 .
目前最新的稳定版本是OpenSSL 1.1.1,OpenSSL 1.0.2之前的版本都已经停止维护了,建议也是停止使用。具体的版本间的差异详见https://github.com/openssl/openssl/blob/master/CHANGES
1.3 加密算法介绍
在生成数据证书是用户可选择不同的加密方式对数据进行加密,常见的加密算法可以分成三类,对称加密算法,非对称加密算法和摘要算法。
1.3.1 对称加密
在对称加密算法中,加密使用的密钥和解密使用的密钥是相同的。也就是说,加密和解密都是使用的同一个密钥。因此对称加密算法要保证安全性的话,密钥要做好保密,只能让使用的人知道,不能对外公开。在对称加密算法中,加密和解密都是使用同一个密钥,不区分公钥和私钥,对称加密主要有四种模式:电子密码本模式(ECB)、加密块链模式(CBC)、加密反馈模式(CFB)、输出反馈模式(OFB)。
对称加密算法的优点在于加解密的高速度和使用长密钥时的难破解性。假设两个用户需要使用对称加密方法加密然后交换数据,则用户最少需要2个密钥并交换使用,如果企业内用户有n个,则整个企业共需要n×(n-1) 个密钥,密钥的生成和分发将成为企业信息部门的恶梦。对称加密算法的安全性取决于加密密钥的保存情况,但要求企业中每一个持有密钥的人都保守秘密是不可能的,他们通常会有意无意的把密钥泄漏出去——如果一个用户使用的密钥被入侵者所获得,入侵者便可以读取该用户密钥加密的所有文档,如果整个企业共用一个加密密钥,那整个企业文档的保密性便无从谈起。
常见的对称加密算法:DES、3DES、DESX、Blowfish、IDEA、RC4、RC5、RC6和AES。
DES是一种分组数据加密技术(先将数据分成固定长度的小数据块,之后进行加密),速度较快,适用于大量数据加密,而3DES是一种基于DES的加密算法,使用3个不同密匙对同一个分组数据块进行3次加密,如此以使得密文强度更高。
相较于DES和3DES算法而言,AES算法有着更高的速度和资源使用效率,安全级别也较之更高了,被称为下一代加密标准。
1.2.2 非对称加密
在非对称加密算法中,加密使用的密钥和解密使用的密钥是不相同的,也称为公私钥加密,也就是说加密使用的密钥和解密使用的密钥不同。
假设两个用户要加密交换数据,双方交换公钥,使用时一方用对方的公钥加密,另一方即可用自己的私钥解密。如果企业中有n个用户,企业需要生成n对密钥,并分发n个公钥。由于公钥是可以公开的,用户只要保管好自己的私钥即可,因此加密密钥的分发将变得十分简单。同时,由于每个用户的私钥是唯一的,其他用户除了可以可以通过信息发送者的公钥来验证信息的来源是否真实,还可以确保发送者无法否认曾发送过该信息。非对称加密的缺点是加解密速度要远远慢于对称加密,在某些极端情况下,甚至能比非对称加密慢上1000倍。
常见的非对称加密算法:RSA、ECC(移动设备用)、Diffie-Hellman、El Gamal、DSA(数字签名用)。
RSA和DSA的安全性及其它各方面性能都差不多,而ECC较之则有着很多的性能优越,包括处理速度,带宽要求,存储空间等等。
1.2.3 摘要算法
摘要算法特别的地方在于它是一种单向算法,用户可以通过Hash算法对目标信息生成一段特定长度的唯一的Hash值,却不能通过这个Hash值重新获得目标信息。因此Hash算法常用在不可还原的密码存储、信息完整性校验等。
常见的Hash算法:MD2、MD4、MD5、HAVAL、SHA、SHA-1、HMAC、HMAC-MD5、HMAC-SHA1。
这几种算法只生成一串不可逆的密文,经常用其效验数据传输过程中是否经过修改,因为相同的生成算法对于同一明文只会生成唯一的密文,若相同算法生成的密文不同,则证明传输数据进行过了修改。通常在数据传说过程前,使用MD5和SHA1算法均需要发送和接收数据双方在数据传送之前就知道密匙生成算法,而HMAC与之不同的是需要生成一个密匙,发送方用此密匙对数据进行摘要处理(生成密文),接收方再利用此密匙对接收到的数据进行摘要处理,再判断生成的密文是否相同。
加密算法的效能通常可以按照算法本身的复杂程度、密钥长度(密钥越长越安全)、加解密速度等来衡量。上述的算法中,除了DES密钥长度不够、MD2速度较慢已逐渐被淘汰外,其他算法仍在目前的加密系统产品中使用。
2. 证书简介
2.1 证书交互过程
在HTTP/HTTPS简介一文中已经详细介绍了HTTPS加密的核心技术TLS的通信流程。在通信流程中为什么HTTPS能够做到数据的安全传输,是因为加密技术以及证书的应用。单向认证,证书交互相关的流程如下:
其中签名的流程如下:
第一步,CA证书的明文消息会使用公开的摘要加密算法对明文信息进行摘要提取得到摘要信息;
第二步,CA机构使用自己的私钥对第一步得到的摘要信息进行加密,得到的信息就是签名;
第三步,CA机构会将明文信息和签名信息放到证书中,这类证书就是数字证书了。所以数字证书主要包含了三方面的内容:证书所有者信息、证书所有者公钥和证书颁发机构的签名;
第四步,消息的接收者接收到数据之后,首先使用同样的方法对原文进行消息摘要,得到摘要A,然后使用CA机构的公钥给数字签名进行解密,得到消息摘要B,最后比较摘要A和摘要B,如果相同,数据原文没有被篡改,证书合法,否则就表示原文被篡改,证书不合法。
通过签名认证后,就可以确定需要连接的服务器是合法的服务器。后面进一步与服务器的证书中的公钥与服务器建立TLS连接(见HTTP/HTTPS简介一文),最后交互数据采用对称加密(TLS过程商量的对称秘钥)。
2.2 证书创建命令及API介绍
2.2.1 通过命令的方式创建证书,网上一搜一大把,这里简单罗列一下相关的命令:
(1)、创建秘钥对
openssl genrsa -out cert.key 2048
(2)、创建证书请求文件,此文件可以发送到CA机构进行签名认证
openssl req -new -key cert.key -out certreq.pem
(3)、创建自签名证书文件
openssl x509 -req -days 365 -in certreq.pem -signkey cert.key -out cert.pem
2.2.2 OpenSSL证书创建API介绍
(1)、RSA_generate_key(),EVP_PKEY_assign_RSA(),主要由此两个函数生成证书秘钥文件;
(2)、X509_REQ_set_pubkey()设置证书请求文件中的公钥信息,X509_NAME_add_entry()、X509_REQ_set_subject_name()加入国家组织省份等信息;
(3)、X509_set_version()设置版本信息,ASN1_INTEGER_set()设置序列号,X509_set_subject_name()/X509_set_issuer_name()设置颁发者发行者信息、X509_time_adj()设置证书有效期信息、X509_sign()证书签名
2.2.3 注意事项
(1)、初始化时重要API调用OpenSSL_add_all_algorithms(),该接口是OpenSSL中调用算法相关API的前提。不调用该API的后果就是程序直接退出,无异常报告,无断点停留。
(2)、Nginx对应配置HTTPS相关选项
可以添加ssl_protocols指定TLS版本号码,或者不填写默认使用支持TLS1.2版本