OpenSSL开发学习总结

阅读 473
收藏 22
2017-10-30
原文链接:mp.weixin.qq.com
本文档是新同学学习OpenSSL开发过程中,文档主要梳理了OpenSSL环境搭建、自建私有CA与证书颁发、文件加密、文件信息摘要提取、数字签名与验证、TLS协议握手与通信建立的整体流程。
一、基础知识

1.对称加密算法

 对称加密算法只使用一个密钥。数据的发送方准备好原始数据和一个加密密钥,加密产生密文,并将密文与密钥发送出去。接收方在解密时,使用同样的密钥对数据进行解密。对称加密算法主要有以下四种加密模式:

 电子密码本模式Electronic Code Book(ECB):最基本的加密模式。将原始数据分为固定长度的若干组,然后对每一组使用同一个密钥进行加密。该模式简单、有利于并行计算,但如此一来相同的明文将被加密成相同的密文,容易受到密码本重放攻击,一般情况下很少使用。

 加密块链模式Cipher Block Chaining(CBC):该模式同样是将原始数据分解成固定长度的若干组,一个加密组在被加密之前,需要与前面已加密组的密文进行异或运算,再将计算结果进行加密得到该组的密文。这种加密模式要求第一组明文在加密之前,需要设置一个初始化变量。选择不同的初始向量,相同的明文加密后会形成不同的密文。由于加密块链模式加密后的密文是上下文相关的,如果一个分组丢失,后面的分组将全部作废。

 加密反馈模式Cipher Feedback Mode(CFB):类似于自同步序列密码,分组加密后,按8位分组将密文和明文进行移位异或后得到输出同时反馈回移位寄存器。其加密步骤如下(解密步骤与加密步骤相反):

1)     加密:加密过程使用了一个64位的移位寄存器,在第一步加密过程中产生64位的初始向量IV;

2)     取初始向量IV最左边的8位与明文前8位进行异或运算,得到的值作为8位密文单元;

3)     8位的密文单元被移至位寄存器的最右端,其它位则向左移动8位,最左端8比特丢弃;

4)     重复步骤1-3继续加密,与第2、3、…段明文输入异或,如此直到所有明文单元都完成加密。

 该模式的优点是数据可以按字节进行加解密。加密反馈模式也是上下文相关的,明文的一个错误会影响后面的密文。

 输出反馈模式Output Feedback Mode(OFB):将分组密码作为同步序列密码运行,和加密反馈模式相似,不过输出反馈模式使用的是前一个N位密文输出分组反馈回移位寄存器。

2.非对称加密算法

 非对称加密算法需要两个密钥:公钥(Public Key)和私钥(Private Key)。公钥与私钥是成对存在的,若用公钥对原始数据进行加密,则只有使用对应的私钥才能解密;若用密钥对原始数据进行签名,则只有用对应的公钥才能验证。由于加密和解密使用的是两个不同的密钥,所以这一类算法称为非对称加密算法。非对称加密算法实现机密信息交换的基本过程如下:

1)     甲方生成一对密钥并将其中的一把作为公钥向其他用户(这里称为乙方)公开;

2)     乙方得到该公用密钥,使用该密钥对要发送的数据进行加密后,发送给甲方;

3)     甲方再用自己保存的私钥,对接收到的信息进行解密。

 此外,甲方还可以使用乙方的公钥对原始数据进行数字签名后,发送给乙方;乙方再用自己的私钥对数据进行验证。

3.消息摘要算法

 消息摘要算法是一种能产生特殊输出格式的算法,这种算法的特点:

1)     加密过程不需要密钥;

2)     无论用户输入什么长度的原始数据,计算出来的消息摘要长度总是固定的,即变长输入,定长输出;

3)     相同的输入将会产生相同的输出;但只要输入的数据发生改变,输出的消息摘要便完全不同;

4)     消息摘要是单向、不可逆的。理论上无法通过反向运算取得原始数据。

通常消息摘要算法被用来做数据完整性校验。

4.数字签名

 数字签名(又称公钥数字签名、电子签章)是一种类似写在纸上的普通的物理签名,但是使用了公钥加密领域的技术实现,用于鉴别数字信息的方法。一套数字签名通常定义两种互补的运算,一个用于签名,另一个用于验证,是非对称加密算法和消息摘要算法结合体。其基本模型如下图所示:

 数字签名的特点主要有:

  • l私钥用于签名,公钥用于验证;

  •  签名时使用原始数据和私钥,验证时使用原始数据、公钥和签名值;

  • l实际使用时,通常需要对原始数据做摘要处理,再利用私钥进行签名。

5.PKI/CA

      关于公共密钥基础设施PKI的一些基础概念与核心组成元素整理如下:

更多关于OpenSSL的背景知识与基本概念,可参考:

http://www.cnblogs.com/f-ck-need-u/p/6089523.html

二、OpenSSL环境搭建

公司的服务器已经预装了较低版本的OpenSSL,但由于此版本存在比较严重的安全漏洞,建议升级OpenSSL版本。

三、OpenSSL自建私有CA与证书颁发

 在自建私有CA之前,先介绍两种不同的PKI/CA建设模式:第三方托管型CA和自建型CA:

 第三方托管型也称服务型,是指CA系统的服务器远程托管在第三方PKI/CA服务提供商的机房,服务提供商需要承担PKI/CA系统的整体建设、运营和维护,通过网络向企业内部提供证书服务的模式。客户只需要购买相应的服务,并完成本地环境的部署即可。

自建型是指企业在内部自行部署CA系统服务器,通过内部局域网实现本地访问的模式。自建模式适用于企业用户量大的内部OA办公,及企业内部分支机构间的安全保护。

 利用OpenSSL,实现自建私有CA并颁发证书的流程具体步骤如下:

 1. 查看OpenSSL配置文件 /etc/pki/tls/openssl.cnf 中关于CA的配置选项和文件路径:

  2. 在本地机器建立CA服务器,生成密钥:

3. 生成CA自签属证书(X.509标准):

该指令是生成证书签署请求,指定了密钥文件路径 private/cakey.pem 和证书文件的生成路径 /etc/pki/CA/cacert.pem,同时规定了证书的过期天数为 3650 天。

4. 初始化工作环境,创建必要的文件:

 5. 证书生成签署请求(客户端生成并发送给CA认证中心):

 6. 客户端把 client.csr 发送给CA认证中心后,CA认证中心为客户端颁发证书(测试过程中,CA认证中心和客户端在同一台电脑上):

自此,完成了自建 CA 给客户颁发证书的所有步骤,证书存放路径:/home/client/ssl/client.crt

四、基于OpenSSL命令行的数字签名和文件加密流程

 首先要明白的是,数字签名的过程是计算出数字摘要,然后使用私钥对数字摘要进行签名,而摘要是使用md5、sha512等算法计算得出的。基于OpenSSL命令行的数字签名和文件加密流程,可以分为文件发送方A和接收方B两个处理模块,数字签名和文件加密的前提是发送方A和接收方B彼此之间已经建立SSL连接,两者均生成了成对的私钥和公钥,并得到了对方的公钥:

1. 对于发送方A:

      1)生成私钥:OpenSSL> genrsa -passout pass:12345678 -out aprivate.pem 2048

      2)生成对应的公钥:OpenSSL> rsa -passin pass:12345678 -pubout -in aprivate.pem -out apublic.pem

      3)使用接收方B的公钥加密文件:OpenSSL> rsautl -encrypt -pubin -inkey bpublic.pem -in data.txt -out encodeData.txt

      4)计算文件的消息摘要:OpenSSL> dgst -sha1 -out md.txt data.txt

      5)用发送方A的私钥给消息摘要签名:OpenSSL> rsautl -sign -inkey aprivate.pem -in md.txt -out signature.bin

      6)最后将加密的文件encodeData.txt和消息摘要签名signature.bin发送给接收方B

    

  2. 对于接收方B:

      1)生成私钥:OpenSSL> genrsa -passout pass:87654321 -out bprivate.pem 2048

      2)生成对应的公钥:OpenSSL> rsa -passin pass:87654321 -pubout -in bprivate.pem -out bpublic.pem

      3)接收A发来的文件 edata.txt,使用用B的私钥进行解密:OpenSSL> rsautl -decrypt -inkey bprivate.pem -in encodeData.txt -out decodeData.txt

      4)计算data.txt的信息摘要:OpenSSL> dgst -sha1 -out md2.txt data.txt

      5)用发送方A的公钥解密数字签名:OpenSSL> rsautl -verify -pubin -inkey apublic.pem -in signature.bin -out md3.txt

      6)最后比较:md2.txt和md3.txt的内容是否完全一致(SHA1(data.txt)= 07a03d3073bb34f57191335e6495190abe7300bc),一致则表示该文件没有被篡改、替换过

五、基于OpenSSL的TLS协议握手与通信建立编程实例

基于OpenSSL的TLS安全通信,客户端和服务器端的编程流程如下图所示:

在使用OpenSSL完成安全通信之前,必须进行相应的SSL/TLS协议初始化工作,包括初始化类库、加载SSL算法与错误信息等等;在开始SSL/TLS会话之前,需要为客户端和服务器制定本次会话所使用的协议,协商完成后将创建CTX会话环境。

 当CTX会话环境建立之后,需要使用socket绑定SSL套接字。SSL套接字是建立在普通TCP套接字的基础之上。成功创建SSL套接字后,客户端与服务器端需分别调用函数SSL_connect()和SSL_accept()完成握手过程,并进行安全的数据传输。

当客户端和服务器之间完成数据通信之后,需要依次关闭SSL套接字、释放SSL套接字,最后释放SSL会话环境。

 以下基于OpenSSL的TLS协议握手与通信建立代码:

 

客户端:

服务器端:

      扫描二维码或阅读原文

       即可享受coding学院1024送出的福利

仅剩3天就截止了呢

评论