Openssl源代码整理学习

时间:2022-10-01 08:54:50

一、基础知识

1.Openssl 简史

OpenSSL项目是加拿大人Eric A.Yang 和Tim J.Hudson开发,现在有Openssl项目小组负责改进和维护;他们是全球一些技术精湛的志愿技术人员,他们的劳动是无偿的,在此我们应该向他们表示崇高的敬意。

Openssl 最早的版本在1995年发布,1998年开始由Openssl项目组维护;

当前最新版本为OpenSSL 1.0.1;开放源代码的SSL产品实现,采用C语言开发;源代码可以在www.openssl.org*下载;

The OpenSSL Project is a collaborative effort to develop a robust, commercial-grade, full-featured, and Open Source toolkit implementing the Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) protocols as well as a full-strength general purpose cryptography library. The project is managed by a worldwide community of volunteers that use the Internet to communicate, plan, and develop the OpenSSL toolkit and its related documentation.

OpenSSL is based on the excellent SSLeay library developed by Eric A. Young and Tim J. Hudson. The OpenSSL toolkit is licensed under an Apache-style licence, which basically means that you are free to get and use it for commercial and non-commercial purposes subject to some simple license conditions.

2.SSL协议和TLS协议

SSL是Netscape开发的专门用户保护Web通讯的,目前版本为3.0。最新版本的TLS 1.0是IETF(工程任务组)制定的一种新的协议,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本。两者差别极小,可以理解为SSL 3.1,它是写入了RFC的。

但在TLS与SSL3.0之间还是存在着差别,主要是它们所支持的加密算法不同,所以TLS与SSL3.0不能互操作。TLS 在SSL v3.0 的基础上,提供了以下增强内容:

1)更安全的MAC算法;

2)更严密的警报;

3)“灰色区域”规范的更明确的定义;

3.对称算法

加解密使用同一个密钥;主要模式有ECB,CBC,CFB,OFB等;

4.摘要算法

特殊格式输出算法,无论输入多长,输出密文都是固定长度的;摘要过程不可逆;

常用算法有MD5(16bytes),SHA1(20bytes);

5.公钥算法

加解密使用不同密钥;密钥不需要交换,即可通信;加密算法和密钥(公钥)是公开的;

常用公钥算法有RSA,DSA,DH和ECC;

6.回调函数

定义在数据结构中,是一个函数指针,方便用户自行编写函数,类似虚函数;

7.X.509(1993)

由国际电信联盟(ITU-T)制定的数字证书标准;包含公钥和用户标志符、CA等;

x509是数字证书的规范,P7和P12是两种封装形式;X.509是常见通用的证书格式。所有的证书都符合为Public key Infrastructure 制定的ITU-T x509国际标准。

PKCS # 7常用的后缀是: P7B, P7C, SPC

PKCS # 12常用的后缀有: P12 ,PFX

X.509 DER编码(ASCII)的后缀是: DER CER CRT

X.509PEM编码(base64)的后缀是:PEM CER CRT

pem格式是经过base64编码的证书,der格式是DER编码的证书;

证书入和导出操作支持四种文件格式。

  • 个人信息交换 (PKCS #12)
    个人信息交换格式(PFX,也称为 PKCS #12)支持安全存储证书、私钥和证书路径中的所有证书。PKCS #12 是唯一可用于导出证书及其私钥的文件格式。
  • 加密消息语法标准 (PKCS #7)
    PKCS #7 格式支持存储证书和证书路径中的所有证书
  • DER 编码的二进制 X.509
    区别编码规则 (DER) 格式支持存储单个证书。该格式不支持存储私钥或证书路径。
  • Base64 编码的 X.509
    Base64 格式支持存储单个证书。该格式不支持存储私钥或证书路径。

cer/crt证书: 用于存储公钥证书的文件格式,它是二进制存放的,不含私钥,不能导入到个人存储区,因为个人存储区存储与私钥相关的数字证书;cer、crt格式只是一个后缀,该后缀的证书可以pem编码的也可以是der编码的;

pfx/p12证书:含有证书和对应的 私钥,可以导入IE的个人证书存储区;

p12格式的证书一般用于证书的分发,里面包含了证书和对应的私钥;

由于Apache Proxy是PEM格式Prefer的,不支持DER经编码的证书,因此,要通过证书的编码转换,把DER编码转换为PEM编码,再经Apache处理。

证书的编码为DER编码,但DER编码的文件是二进制格式不利于读写和传播,所以对DER编码的数据进行BASE64编码形成了PEM。

8.PKCS系列标准

由RSA数字安全公司但呢个制定的公钥密码学标准,包含证书申请、更新、CRL、DS等;

其中PKCS7,定义了通用的消息语法,含数字签名和加密,与PEM兼容,互相转化;

PKCS12,描述个人信息交换语法,打包公钥、私钥、证书和其他信息;

PKCS 全称是 Public-Key Cryptography Standards ,是由 RSA 实验室与其它安全系统开发商为促进公钥密码的发展而制订的一系列标准,PKCS 目前共发布过 15 个标准。 常用的有:
PKCS#7 Cryptographic Message Syntax Standard
PKCS#10 Certification Request Standard
PKCS#12 Personal Information Exchange Syntax Standard

比较:

P7一般是把证书分成两个文件,一个公钥一个私钥,有PEM和DER两种编码方式。PEM比较多见,就是纯文本的,P7一般是分发公钥用,看到的就是一串可见字符串,扩展名经常是.crt,.cer,.key等。DER是二进制编码。

P12是把证书压成一个文件,.pfx 。主要是考虑分发证书,私钥是要绝对保密的,不能随便以文本方式散播。所以P7格式不适合分发。.pfx中可以加密码保护,所以相对安全些。

在实践中要中,用户证书都是放在USB Key中分发,服务器证书经常还是以文件方式分发。服务器证书和用户证书,都是X509证书,就是里面的属性有区别。

7.OCSP在线证书状态协议

由IETF颁布,用于检查数字证书在某一交易时刻是否有效的标准;提供快捷状态查询通道;

8.LDAP轻量级目录访问协议

简化了X.500目录访问协议,广泛应用于证书发布、CRL信息发布、CA政策等;

9.PKI(Public Key Infrastructure )

PKI,"公钥基础设施";X.509标准中,将PKI定义为支持公开密钥管理并能支持认证、加密、完整性和可追究性服务的基础设施;

更多:

完整的PKI系统必须具有权威认证机构(CA)、数字证书库、密钥备份及恢复系统、证书作废系统、应用接口(API)等基本构成部分,构建PKI也将围绕着这五大系统来着手构建。 核心技术就围绕着数字证书的申请、颁发、使用与撤销等整个生命周期进行展开;PKI采用数字证书方式进行服务,即通过第三方颁发的数字证书证明末端实体的密钥,而不是在线查询或在线分发;

PKI与应用的分离也是PKI作为基础设施的重要标志,实际上就是网络社会的一次“社会分工”,这种分工可能会成为网络应用发展史上的重要里程碑。

二、Openssl源码分析

1.简介

开源SSL安全工具,包含SSL协议实现,大量软算法(对称/非对称/摘要),非对称算法密钥生成,ASN.1编解码库、证书请求(pscs10) 编解码,数字证书、CRL编解码,OCSP协议,pkcs7标准实现和pkcs12个人数字证书格式实现等功能;

使用C语言开发,跨平台优越;

2.源码框架

主要由eay基础函数库、ssl库、工具、demo和test组成;

Eay库源码,在crypto目录下,包含:

1) asn.1 DER编码解码(crypto/asn.1目录),包含数字证书请求,CRL吊销列表及pkcs8编解码函数;

2) 抽象IO(BIO,crypto/bio目录),包含各种输入输出抽象,文件、内存、stdio、socket、SSL;

3) 大数运算(crypto/bn目录),用于非对称算法密钥生成和各种加解密;

4) 字符缓存(crypto/buffer目录);

5) 配置文件读取(crypto/conf 目录),主要配置文件为openssl.cnf。本目录实现改格式配置文件的读取;

6) DSO动态共享对象(crypto/dso目录),抽象各平台动态库加载函数,提供统一接口;

7) 硬件引擎(crypto/engine目录),提供了规定接口;

8) 错误处理(cryto/err目录),提供处理接口;以堆栈显示错误;

9) 对称算法、非对称算法及摘要算法封装(crypto/evp目录)

10) HMAC(crypto/hmac目录),实现基于对称算法的MAC;

11) Hash表(crypto/lhash目录),实现散列表数据结构;

12) OCSP数字证书在线认证(crypto/ocsp目录),实现ocsp协议的编解码等;

13) PEM文件格式处理(crypto/pem目录),生成和读取PEM文件;

14) Pkcs7消息语法(crypto/pkcs7目录),实现构造和解析PKCS7消息;

15) Pkcs12个人证书格式(crypto/pkcs12目录),实现pkcs12证书构造和解析;

16) 队列(crypto/pqueue目录),实现队列数据结构,用于DTLS;

17) 随机数(crypto/rand目录),实现伪随机数生成,支持用户自定义;

18) 堆栈(crypto/rand目录),实现堆栈数据结构;

19) 线程支持(crypto/threads),openssl支持多线程,但是用户必须实现相关接口;

20) 文本数据库(crypto/txt_db目录);

21) X509数字证书(crypto/x509目录),包括数字证书申请、证书和CRL构造解析和签名验证;

22) 对称算法(crypto/aes、crypto/bf、crypto/cast、crypto/omp和crypto/des等);

23) 非对称算法(crypto/dh、crypto/dsa、crytpo/ec和crypto/ecdh);

24) 摘要算法(crypto/md2/4/5/sha)以及密钥交换/认证算法(crypto/dh和crypto/krb5);

SSL库源代码在ssl目录下,包含sslv2,sslv3,tlsv1和DTLS的源码;包含客户端源码、服务器源码、通用、底层包、方法以及协议相关密钥计算源码;

工具源码在crypto/apps目录;demo中有硬件引擎engines源码;测试源码在test中;

三、Openssl具体模块举例

1.PEM格式

使用PEM(Privacy Enhanced Mail),来存放各种信息,是openssl默认信息存放方式;

文件包含信息:内容类型、头信息(加密算法和初始化变量iv)、信息体(BASE64编码的)三部分;

PEM格式文件生成过程:

1)将个数据DER编码;如有需要,进行加密处理;

2)根据是否加密,构造PEM头,将1中数据进行BASE64编码,放入PEM文件;

文件内容举例如下图:

编程相关:

PEM模块实现位于/crypto/pem目录下,依赖ASN1模块,支持格式见/crypto/pem/pem.h文件;函数定义主要是read和write,见crypto/pem/pem.h;

2.通用数据结构

主要用于数字证书申请,数字证书和CRL中;

借ASN1库实现DER编解码;包含set和get操作;

编程相关:数据结构定义放在crypto/x509/x509.h中。

3.证书申请

生成x509数字证书前,用户先提交证书申请文件,然后CA来签发证书;

过程大致:

1)用户生成自己公私钥对;构造证书申请文件,符合PKCS10标准;包含用户信息、

公钥等,并用私钥签名(即自签名证书);

2)用户将证书申请提交给CA;

3)CA验证签名,提取用户信息,并加入如颁发者信息等,用CA私钥签发;

编程相关:

X509证书申请数据结构定义在crypto/x509.h中,包含两部分,X509_REQ_INFO和

X509_REQ。

4.X509数字证书

将用户身份与公钥绑定的载体,符合x509格式,必须有CA的签名;用户不仅有数字证书,

还有对应的私钥;

数字证书包含内容有,版本、序列号、算法、颁布着、有效时间、共要信息、ID等;

编程相关:

源码在crypto/x509和crypto/x509v3中,实现了结构设置、证书验证摘要、公钥导入导出等;

5.CRL

证书吊销列表(Certificate Revocation List),是包含吊销列表的数据结构;是离线的证书状态信息,类似黑名单;分完全CRL和增量CRL;

基本CRL信息有,吊销证书序列号、时间、原因、CRL签名等;

数据结构在cry pto/x509/x509.h中;

编程相关:

6.PKCS7

加密消息语法(pkcs7),是各种消息存放的格式标准;如数据,签名、数字信封、摘要和加密数据;实现在crypto/pkcs7中;

编程相关:

7.PKCS12

个人数字证书标准PKCS12,用于存放证书、CRL、用户私钥以及证书链;其中私钥是加密存放的;实现在crypto/pkcs12目录;

编程相关:

代码结构如下,

数据结构定义在crpto/pkcs12/pkcs12.h中;

7.SSL实现

由netscape公司提出,有sslv2和sslv3,当前形成标准有tls协议和DTLS;保证通信信道安全,提供数据加密、身份验证以及消息完整性保护;另支持数据压缩;通过握手协商各种算法和密钥;

源码在ssl目录,有客户端(xx_clnt.c)、服务器(xx_srvr.c)、加密实现(xx_enc.c)、记录协议实现(xx_pkt.c)、METHOD方法(xx_meth.c)、双方握手方法(xx_both.c),以及对外函数(xx_lib.c)

建立SSL测试环境:

1)建立自己的CA;apps中运行脚本:./CA.sh -newca,生成demoCA目录,含ca证书和私钥;

2)生成客户端和服务器端证书申请;

#客户端的

Openssl> req -newkey rsa:1024 -out req1.pem -keyout sslclientkey.pem

#服务器端

>req -newkey rsa:1024 -out req2.pem  -keyout  sslserverkey.pem

3)签发客户端和服务器端证书;

>ca -in req1.pem -out sslclientcert.pem

#CA的签发,必须在apps目录下进行;

$ cd /dzrSSL/apps

> ca  -in demoCA/mySSLtest/req2.pem -out demoCA/mySSLtest/sslservercert.pem.

4)运行ssl服务器和客户端;

Openssl>s_server -cert sslservercert.pem -key sslserverkey.pem -CAfile demoCA/cacert.pem -ssl3

>s_client -ssl3 -CAfile demoCA/cacert.pem

5)验证客户端证书

6)制定加密套件

7)制定私钥加密口

编程相关:

主要数据结构在ssl.h中,有SSL_CTX、SSL和SSL_SESSION;

SSL_CTX数据结构用于SSL握手前准备,设置CA文件和目录、设置SSL握手中的证书文件和私钥、设置协议版本等;SSL结构主要用于SSL握手以及传送数据;SSL_SESSION保存主密钥、session id/读写加解密钥、读写MAC密钥信息;

SSL_CTX缓存了所有SSL_SESSION信息,SSL包含SSL_CTX数据;通过SSL数据查找session id,实现SESSION重用;

加密套件,用openssl>ciphers命令查询;

参考

1.《SSL协议及OPENSSL源代码分析》,陈岩文档,2009;

2.《Openssl编程》,江南计算技术研究所,赵春平,forxy@126,;

3.《OpenSSL与网络信息安全——基础、结构和指令》,王志海,2004;

4.《Network Sercurity with OpenSSL》,Pravir Chandra,MattMessier,John Viega,2002;