openssl教程完全版.doc
《openssl教程完全版.doc》由会员分享,可在线阅读,更多相关《openssl教程完全版.doc(653页珍藏版)》请在冰点文库上搜索。
Openssl程式設計
Openssl程式設計
第一章 基础知识 8
1.1 对称算法 8
1.2 摘要算法 9
1.3 公钥算法 9
1.4 回调函数 11
第二章 openssl简介 13
2.1 openssl简介 13
2.2 openssl安装 13
2.2.1 linux下的安装 13
2.2.2 windows编译与安装 14
2.3 openssl源代码 14
2.4 openssl学习方法 16
第三章 堆栈 17
3.1 openssl堆栈 17
3.2 数据结构 17
3.3 源码 18
3.4 定义用户自己的堆栈函数 18
3.5 编程示例 19
第四章 哈希表 21
4.1 哈希表 21
4.2 哈希表数据结构 21
4.3 函数说明 23
4.4 编程示例 25
第五章 内存分配 27
5.1 openssl内存分配 27
5.2 内存数据结构 27
5.3 主要函数 28
5.4 编程示例 29
第六章 动态模块加载 30
6.1 动态库加载 30
6.2 DSO概述 30
6.3 数据结构 31
6.4 编程示例 32
第七章 抽象IO 34
7.1 openssl抽象IO 34
7.2 数据结构 34
7.3 BIO函数 36
7.4 编程示例 36
7.4.1 membio 36
7.4.2 filebio 37
7.4.3 socketbio 38
7.4.4 mdBIO 39
7.4.5 cipherBIO 40
7.4.6 sslBIO 41
7.4.7 其他示例 42
第八章 配置文件 43
8.1 概述 43
8.2 openssl配置文件读取 43
8.3 主要函数 44
8.4 编程示例 44
第九章 随机数 46
9.1 随机数 46
9.2 openssl随机数数据结构与源码 46
9.3 主要函数 48
9.4 编程示例 48
第十章 文本数据库 50
10.1 概述 50
10.2 数据结构 51
10.3 函数说明 51
10.4 编程示例 52
第十一章 大数 54
11.1 介绍 54
11.2 openssl大数表示 54
11.3 大数函数 55
11.4 使用示例 58
第十二章 BASE64编解码 64
12.1 BASE64编码介绍 64
12.2 BASE64编解码原理 64
12.3 主要函数 65
12.4 编程示例 66
第十三章 ASN1库 68
13.1 ASN1简介 68
13.2 DER编码 70
13.3 ASN1基本类型示例 70
13.4 openssl的ASN.1库 73
13.5 用openssl的ASN.1库DER编解码 74
13.6 Openssl的ASN.1宏 74
13.7 ASN1常用函数 75
13.8 属性证书编码 89
第十四章 错误处理 93
14.1 概述 93
14.2 数据结构 93
14.3 主要函数 95
14.4 编程示例 97
第十五章 摘要与HMAC 100
15.1 概述 100
15.2 openssl摘要实现 100
15.3 函数说明 101
15.4 编程示例 101
15.5 HMAC 103
第十六章 数据压缩 104
16.1 简介 104
16.2 数据结构 104
16.3 函数说明 105
16.4 openssl中压缩算法协商 106
16.5 编程示例 106
第十七章 RSA 107
17.1RSA介绍 107
17.2 openssl的RSA实现 107
17.3 RSA签名与验证过程 108
17.4 数据结构 109
17.4.1RSA_METHOD 109
17.4.2 RSA 110
17.5 主要函数 110
17.6编程示例 112
17.6.1密钥生成 112
17.6.2 RSA加解密运算 113
17.6.3签名与验证 116
第十八章 DSA 119
18.1 DSA简介 119
18.2 openssl的DSA实现 120
18.3 DSA数据结构 120
18.4 主要函数 121
18.5 编程示例 122
18.5.1密钥生成 122
18.5.2签名与验证 124
第十九章DH 126
19.1 DH算法介绍 126
19.2 openssl的DH实现 127
19.3数据结构 127
19.4 主要函数 128
19.5 编程示例 129
第二十章 椭圆曲线 132
20.1 ECC介绍 132
20.2 openssl的ECC实现 133
20.3 主要函数 135
20.3.1参数设置 135
20.3.2参数获取 136
20.3.3转化函数 137
20.3.4其他函数 137
20.4 编程示例 139
第二十一章 EVP 143
21.1EVP简介 143
21.2数据结构 143
21.2.1 EVP_PKEY 144
21.2.2 EVP_MD 144
21.2.3 EVP_CIPHER 145
21.2.4 EVP_CIPHER_CTX 146
21.3源码结构 147
21.4摘要函数 147
21.5对称加解密函数 148
21.6非对称函数 149
21.7 BASE64编解码函数 149
21.8其他函数 150
21.9对称加密过程 152
21.10 编程示例 152
第二十二章 PEM格式 159
22.1 PEM概述 159
22.2 openssl的PEM实现 160
22.3 PEM函数 161
22.4 编程示例 161
第二十三章 Engine 165
23.1 Engine概述 165
23.2 Engine支持的原理 165
23.3 Engine数据结构 166
23.4 openssl的Engine源码 167
23.5 Engine函数 167
23.6 实现Engine示例 169
第二十四章 通用数据结构 182
24.1通用数据结构 182
24.2 X509_ALGOR 182
24.3 X509_VAL 184
24.4 X509_SIG 185
24.5 X509_NAME_ENTRY 186
24.6 X509_NAME 187
24.7 X509_EXTENSION 193
24.8 X509_ATTRIBUTE 199
24.9 GENERAL_NAME 200
第二十五章 证书申请 203
25.1 证书申请介绍 203
25.2 数据结构 203
25.3 主要函数 204
25.4 编程示例 206
25.4.1生成证书请求文件 206
25.4.2 解码证书请求文件 208
第二十六章 X509数字证书 210
26.1 X509数字证书 210
26.2 opessl实现 210
26.3 X509数据结构 210
26.4 X509_TRUST与X509_CERT_AUX 214
26.5 X509_PURPOSE 215
26.6 主要函数 218
26.7 证书验证 221
26.7.1证书验证项 221
26.7.2 Openssl中的证书验证 221
第二十七章 OCSP 222
27.1 概述 222
27.2 openssl实现 222
27.3 主要函数 222
27.4编程示例 227
第二十八章 CRL 228
28.1 CRL介绍 228
28.2 数据结构 228
28.3 CRL函数 230
28.4 编程示例 231
第二十九章 PKCS7 233
29.1概述 233
29.2 数据结构 233
29.3 函数 234
29.4 消息编解码 235
29.4.1 data 235
29.4.2 signeddata 236
29.4.3 enveloped 237
29.4.4 signed_and_enveloped 238
29.4.5 digest 238
29.4.6 encrypted 239
29.4.7 读取PEM 239
29.4.8 解码pkcs7 240
第三十章 PKCS12 241
30.1 概述 241
30.2 openss实现 241
30.3数据结构 242
30.4函数 243
30.5 编程示例 245
第三十一章 SSL实现 254
31.1概述 254
31.2 openssl实现 254
31.3 建立SSL测试环境 254
31.4 数据结构 256
31.5 加密套件 256
31.6 密钥信息 257
31.7 SESSION 258
31.8 多线程支持 258
31.9 编程示例 259
31.10 函数 270
第三十二章 Openssl命令 272
32.1概述 272
32.2 asn1parse 272
32.3 dgst 274
32.4 gendh 275
32.5 passwd 276
32.6 rand 276
32.7 genrsa 277
32.8 req 278
32.9 x509 280
32.10 version 283
32.11 speed 283
32.12 sess_id 284
32.13 s_server 284
32.14 s_client 286
32.15 rsa 288
32.16 pkcs7 289
32.17 dsaparam 290
32.18 gendsa 291
32.19 enc 291
32.20 ciphers 292
32.21 CA 293
32.22 verify 296
32.23 rsatul 297
32.24 crl 299
32.25 crl2pkcs7 300
32.26 errstr 300
32.27ocsp 301
32.28 pkcs12 304
32.29 pkcs8 306
32.30 s_time 307
32.31dhparam和dh 308
32.32 ecparam 309
32.33 ec 310
32.34 dsa 311
32.35 nseq 312
32.36 prime 313
32.37 smime 313
第一章 基礎知識
1.1 對稱演算法
對稱演算法使用一個金鑰。
給定一個明文和一個金鑰,加密產生密文,其長度和明文大致相同。
解密時,使用讀金鑰與加密金鑰相同。
對稱演算法主要有四種加密模式:
(1) 電子密碼本模式 ElectronicCodeBook(ECB)
這種模式是最早採用和最簡單的模式,它將加密的資料分成若干組,每組的大小跟加密金鑰長度相同,然後每組都用相同的金鑰進行加密。
其缺點是:
電子編碼薄模式用一個金鑰加密消息的所有塊,如果原消息中重複明文塊,則加密消息中的相應密文塊也會重複,因此,電子編碼薄模式適於加密小消息。
(2)加密塊鏈模式 CipherBlockChaining(CBC)
CBC模式的加密首先也是將明文分成固定長度的塊,然後將前面一個加密塊輸出的密文與下一個要加密的明文塊進行異或操作,將計算結果再用金鑰進行加密得到密文。
第一明文塊加密的時候,因為前面沒有加密的密文,所以需要一個初始化向量。
跟ECB方式不一樣,通過連接關係,使得密文跟明文不再是一一對應的關係,破解起來更困難,而且克服了只要簡單調換密文塊可能達到目的的攻擊。
(3)加密回饋模式 CipherFeedbackMode(CFB)
面向字元的應用程式的加密要使用流加密法,可以使用加密回饋模式。
在此模式下,資料用更小的單元加密,如可以是8位,這個長度小於定義的塊長(通常是64位)。
其加密步驟是:
a) 使用64位的初始化向量。
初始化向量放在移位暫存器中,在第一步加密,產生相應的64位初始化密文;
b) 始化向量最左邊的8位與明文前8位進行異或運算,產生密文第一部分(假設為c),然後將c傳輸到接收方;
c) 向量的位(即初始化向量所在的移位暫存器內容)左移8位元,使移位暫存器最右邊的8位元為不可預測的資料,在其中填入c的內容;
d) 第1-3步,直到加密所有的明文單元。
解密過程相反
4)輸出回饋模式 OutputFeedbackMode(OFB)
輸出回饋模式與CFB相似,惟一差別是,CFB中密文填入加密過程下一階段,而在OFB中,初始化向量加密過程的輸入填入加密過程下一階段。
1.2 摘要演算法
摘要演算法是一種能產生特殊輸出格式的演算法,這種演算法的特點是:
無論使用者輸入什麼長度的原始資料,經過計算後輸出的密文都是固定長度的,這種演算法的原理是根據一定的運算規則對原資料進行某種形式的提取,這種提取就是摘要,被摘要的資料內容與原資料有密切聯繫,只要原資料稍有改變,輸出的“摘要”便完全不同,因此,基於這種原理的演算法便能對資料完整性提供較為健全的保障。
但是,由於輸出的密文是提取原資料經過處理的定長值,所以它已經不能還原為原資料,即消息摘要演算法是不可逆的,理論上無法通過反向運算取得原資料內容,因此它通常只能被用來做資料完整性驗證。
如今常用的“消息摘要”演算法經歷了多年驗證發展而保留下來的演算法已經不多,這其中包括MD2、MD4、MD5、SHA、SHA-1/256/383/512等。
常用的摘要演算法主要有MD5和SHA1。
D5的輸出結果為16位元組,sha1的輸出結果為20位元組。
1.3 公開金鑰演算法
在公開金鑰密碼系統中,加密和解密使用的是不同的金鑰,這兩個金鑰之間存在著相互依存關係:
即用其中任一個金鑰加密的資訊只能用另一個金鑰進行解密。
這使得通信雙方無需事先交換金鑰就可進行保密通信。
其中加密金鑰和演算法是對外公開的,人人都可以通過這個金鑰加密檔然後發給收信者,這個加密金鑰又稱為公開金鑰;而收信者收到加密檔後,它可以使用他的解密金鑰解密,這個金鑰是由他自己私人掌管的,並不需要分發,因此又成稱為私密金鑰,這就解決了金鑰分發的問題。
主要的公開金鑰演算法有:
RSA、DSA、DH和ECC。
(1)RSA演算法
當前最著名、應用最廣泛的公開金鑰系統RSA是在1978年,由美國麻省理工學院(MIT)的Rivest、Shamir和Adleman在題為《獲得數位簽章和公開鑰密碼系統的方法》的論文中提出的。
它是一個基於數論的非對稱(公開鑰)密碼體制,是一種區塊編碼器體制。
其名稱來自於三個發明者的姓名首字母。
它的安全性是基於大整數素因數分解的困難性,而大整數因數分解問題是數學上的著名難題,至今沒有有效的方法予以解決,因此可以確保RSA演算法的安全性。
RSA系統是公開金鑰系統的最具有典型意義的方法,大多數使用公開金鑰密碼進行加密和數位簽章的產品和標準使用的都是RSA演算法。
RSA演算法是第一個既能用於資料加密也能用於數位簽章的演算法,因此它為公用網絡上資訊的加密和鑒別提供了一種基本的方法。
它通常是先生成一對RSA金鑰,其中之一是保密金鑰,由用戶保存;另一個為公開金鑰,可對外公開,甚至可在網路服務器中註冊,人們用公開金鑰加密檔發送給個人,個人就可以用私密金鑰解密接受。
為提高保密強度,RSA金鑰至少為500位長,一般推薦使用1024位。
RSA演算法是R.Rivest、A.Shamir和L.Adleman于1977年在美國麻省理工學院開發,於1978年首次公佈。
RSA公開金鑰密碼演算法是目前網路上進行保密通信和數位簽章的最有效的安全演算法之一。
RSA演算法的安全性基於數論中大素數分解的困難性,所以,RSA需採用足夠大的整數。
因數分解越困難,密碼就越難以破譯,加密強度就越高。
其演算法如下:
A.選擇兩質數p、q
B.計算n=p*q
C.計算n的歐拉函數Φ(n)=(p-1)(q-1)
D.選擇整數e,使e與Φ(n)互質,且1E.計算d,使d*e=1modΦ(n)
其中,公開金鑰KU={e,n},私密金鑰KR={d,n}。
加密/解密過程:
利用RSA加密,首先需將明文數位化,取長度小於log2n位元的數位作為明文塊。
對於明文塊M和密文塊C,加/解密的形式如下:
加密:
C=Memodn
解密:
M=Cdmodn=(Me)dmodn=Medmodn
RSA的安全性基於大數分解質因數的困難性。
因為若n被分解為n=p*q,則Φ(n)、e、d可依次求得。
目前,因式分解速度最快的方法的時間複雜性為exp(sqrt(ln(n)lnln(n)))。
統計資料表明,在重要應用中,使用512位的金鑰已不安全,需要採用1024位元的金鑰。
(2)DSA演算法
DSA(Digital Signature Algorithm,數位簽章演算法,用作數位簽章標準的一部分),它是另一種公開金鑰演算法,它不能用作加密,只用作數位簽章。
DSA使用公開金鑰,為接受者驗證資料的完整性和資料發送者的身份。
它也可用於由協力廠商去確定簽名和所簽資料的真實性。
DSA演算法的安全性基於解離散對數的困難性,這類簽字標準具有較大的相容性和適用性,成為網路安全體系的基本構件之一。
DSA簽名演算法中用到了以下參數:
p是L位長的素數,其中L從512到1024且是64的倍數。
q是160位長且與p-1互素的因數 ,其中h是小於p-1並且滿足 大於1的任意數。
x是小於q的數。
另外,演算法使用一個單向散列函數H(m)。
標準指定了安全散列演算法(SHA)。
三個參數p,q和g是公開的,且可以被網路中所有的使用者公有。
私人金鑰是x,公開金鑰是y。
對消息m簽名時:
(1) 發送者產生一個小於q的亂數k。
(2) 發送者產生:
r和s就是發送者的簽名,發送者將它們發送給接受者。
(3) 接受者通過計算來驗證簽名:
如果v=r,則簽名有效。
(3)Diffie-Hellman金鑰交換
DH演算法是W.Diffie和M.Hellman提出的。
此演算法是最早的公開金鑰演算法。
它實質是一個通信雙方進行金鑰協定的協議:
兩個實體中的任何一個使用自己的私密金鑰和另一實體的公開金鑰,得到一個對稱金鑰,這一對稱金鑰其它實體都計算不出來。
DH演算法的安全性基於有限域上計算離散對數的困難性。
離散對數的研究現狀表明:
所使用的DH金鑰至少需要1024位元,才能保證有足夠的中、長期安全。
(4) 橢圓曲線密碼體制(ECC)
1985年,N.Koblitz和V.Miller分別獨立提出了橢圓曲線密碼體制(ECC),其依據就是定義在橢圓曲線點群上的離散對數問題的難解性。
為了用橢圓曲線構造密碼系統,首先需要找到一個單向陷門函數,橢圓曲線上的數量乘就是這樣的單向陷門函數。
橢圓曲線的數量乘是這樣定義的:
設E為域K上的橢圓曲線,G為E上的一點,這個點被一個正整數k相乘的乘法定義為k個G相加,因而有
kG=G+G+…+G(共有k個G)
若存在橢圓曲線上的另一點N≠G,滿足方程kG=N。
容易看出,給定k和G,計算N相對容易。
而給定N和G,計算k=logGN相對困難。
這就是橢圓曲線離散對數問題。
離散對數求解是非常困難的。
橢圓曲線離散對數問題比有限域上的離散對數問題更難求解。
對於有理點數有大素數因數的橢圓離散對數問題,目前還沒有有效的攻擊方法。
1.4 回呼函數
Openssl中大量用到了回呼函數。
回呼函數一般定義在資料結構中,是一個函數指標。
通過回呼函數,客戶可以自行編寫函數,讓openssl函數來調用它,即使用者調用openssl提供的函數,openssl函數再回檔使用者提供的函數。
這樣方便了使用者對openssl函數操作的控制。
在openssl實現函數中,它一般會實現一個預設的函數來進行處理,如果用戶不設置回呼函數,則採用它預設的函數。
回呼函數舉例:
標頭檔:
#ifndefRANDOM_H
#defineRANDOM_H1
typedefint*callback_random(char*random,intlen);
void set_callback(callback_random*cb);
int genrate_random(char*random,intlen);
#endif
原始程式碼:
#include"random.h"
#include
callback_random*cb_rand=NULL;
staticintdefault_random(char*random,intlen
{
memset(random,0x01,len);
return0;
}
void set_callback(callback_random*cb)
{
cb_rand=cb;
}
int genrate_random(char*random,intlen)
{
if(cb_rand==NULL)
returndefault_random(random,len);
else
returncb_rand(random,len);
return0;
}
測試代碼:
#include"random.h"
staticintmy_rand(char*rand,intlen)
{
memset(rand,0x02,len);
return0;
}
int main()
{
char random[10];
int ret;
set_callback(my_rand);
ret=genrate_random(random,10);
return0;
}
本例子用來生產簡單的亂數,如果用戶提供了生成亂數回呼函數,則生成亂數採用用戶的方法,否則採用默認的方法。
第二章 openssl簡介
2.1 openssl簡介
openssl是一個功能豐富且自包含的開源安全工具箱。
它提供的主要功能有:
SSL協議實現(包括SSLv2、SSLv3和TLSv1)、大量軟演算法(對稱/非對稱/摘要)、大數運算、非對稱演算法金鑰生成、ASN.1編解碼庫、證書請求(PKCS10)編解碼、數位憑證編解碼、CRL編解碼、OCSP協議、數位憑證驗證、PKCS7標準實現和PKCS12個人數位憑證格式實現等功能。
openssl採用C語言作為開發語言,這使得它具有優秀的跨平臺性能。
openssl支援Linux、UNIX、windows、Mac等平臺。
openssl目前最新的版本