《openssl编程》之基础知识
第一章?基礎知識
1.1?對稱算法
?對稱算法使用一個密鑰。給定一個明文和一個密鑰,加密產(chǎn)生密文,其長度和明文大致相同。解密時,使用讀密鑰與加密密鑰相同。
?對稱算法主要有四種加密模式:
(1)?電子密碼本模式??Electronic?Code?Book(ECB)
這種模式是最早采用和最簡單的模式,它將加密的數(shù)據(jù)分成若干組,每組的大小跟加密密鑰長度相同,然后每組都用相同的密鑰進行加密。
其缺點是:電子編碼薄模式用一個密鑰加密消息的所有塊,如果原消息中重復明文塊,則加密消息中的相應密文塊也會重復,因此,電子編碼薄模式適于加密小消息。
(2)加密塊鏈模式?Cipher?Block?Chaining(CBC)
CBC模式的加密首先也是將明文分成固定長度的塊,然后將前面一個加密塊輸出的密文與下一個要加密的明文塊進行異或操作,將計算結(jié)果再用密鑰進行加密得到密文。第一明文塊加密的時候,因為前面沒有加密的密文,所以需要一個初始化向量。跟ECB方式不一樣,通過連接關(guān)系,使得密文跟明文不再是一一對應的關(guān)系,破解起來更困難,而且克服了只要簡單調(diào)換密文塊可能達到目的的攻擊。
(3)加密反饋模式??????????Cipher?Feedback?Mode(CFB)
面向字符的應用程序的加密要使用流加密法,可以使用加密反饋模式。在此模式下,數(shù)據(jù)用更小的單元加密,如可以是8位,這個長度小于定義的塊長(通常是64位)。其加密步驟是:
a)?使用64位的初始化向量。初始化向量放在移位寄存器中,在第一步加密,產(chǎn)生相應的64位初始化密文; b)?始化向量最左邊的8位與明文前8位進行異或運算,產(chǎn)生密文第一部分(假設為c),然后將c傳輸?shù)浇邮辗?#xff1b;
c)?向量的位(即初始化向量所在的移位寄存器內(nèi)容)左移8位,使移位寄存器最右邊的8位為不可預測的數(shù)據(jù),在其中填入c的內(nèi)容; d)?第1-3步,直到加密所有的明文單元。
解密過程相反
4)輸出反饋模式??????????Output?Feedback?Mode(OFB)
輸出反饋模式與CFB相似,惟一差別是,CFB中密文填入加密過程下一階段,而在OFB中,初始化向量加密過程的輸入填入加密過程下一階段。
1.2?摘要算法
?摘要算法是一種能產(chǎn)生特殊輸出格式的算法,這種算法的特點是:無論用戶輸入什么長度的原始數(shù)據(jù),經(jīng)過計算后輸出的密文都是固定長度的,這種算法的原理是根據(jù)一定的運算規(guī)則對原數(shù)據(jù)進行某種形式的提取,這種提取就是摘要,被摘要的數(shù)據(jù)內(nèi)容與原數(shù)據(jù)有密切聯(lián)系,只要原數(shù)據(jù)稍有改變,輸出的“摘要”便完全不同,因此,基于這種原理的算法便能對數(shù)據(jù)完整性提供較為健全的保障。但是,由于輸出的密文是提取原數(shù)據(jù)經(jīng)過處理的定長值,所以它已經(jīng)不能還原為原數(shù)據(jù),即消息摘要算法是不可逆的,理論上無法通過反向運算取得原數(shù)據(jù)內(nèi)容,因此它通常只能被用來做數(shù)據(jù)完整性驗證。
如今常用的“消息摘要”算法經(jīng)歷了多年驗證發(fā)展而保留下來的算法已經(jīng)不多,這其中包括MD2、MD4、MD5、SHA、SHA-1/256/383/512等。
?常用的摘要算法主要有MD5和SHA1。D5的輸出結(jié)果為16字節(jié),sha1的輸出結(jié)果為20字節(jié)。
1.3?公鑰算法
在公鑰密碼系統(tǒng)中,加密和解密使用的是不同的密鑰,這兩個密鑰之間存在著相互依存關(guān)系:即用其中任一個密鑰加密的信息只能用另一個密鑰進行解密。這使得通信雙方無需事先交換密鑰就可進行保密通信。其中加密密鑰和算法是對外公開的,人人都可以通過這個密鑰加密文件然后發(fā)給收信者,這個加密密鑰又稱為公鑰;而收信者收到加密文件后,它可以使用他的解密密鑰解密,這個密鑰是由他自己私人掌管的,并不需要分發(fā),因此又成稱為私鑰,這就解決了密鑰分發(fā)的問題。
主要的公鑰算法有:RSA、DSA、DH和ECC。
(1)RSA算法
當前最著名、應用最廣泛的公鑰系統(tǒng)RSA是在1978年,由美國麻省理工學院(MIT)的Rivest、Shamir和Adleman在題為《獲得數(shù)字簽名和公開鑰密碼系統(tǒng)的方法》的論文中提出的。它是一個基于數(shù)論的非對稱(公開鑰)密碼體制,是一種分組密碼體制。其名稱來自于三個發(fā)明者的姓名首字母。?它的安全性是基于大整數(shù)素因子分解的困難性,而大整數(shù)因子分解問題是數(shù)學上的著名難題,至今沒有有效的方法予以解決,因此可以確保RSA算法的安全性。RSA系統(tǒng)是公鑰系統(tǒng)的最具有典型意義的方法,大多數(shù)使用公鑰密碼進行加密和數(shù)字簽名的產(chǎn)品和標準使用的都是RSA算法。
RSA算法是第一個既能用于數(shù)據(jù)加密也能用于數(shù)字簽名的算法,因此它為公用網(wǎng)絡上信息的加密和鑒別提供了一種基本的方法。它通常是先生成一對RSA?密鑰,其中之一是保密密鑰,由用戶保存;另一個為公開密鑰,可對外公開,甚至可在網(wǎng)絡服務器中注冊,人們用公鑰加密文件發(fā)送給個人,個人就可以用私鑰解密接受。為提高保密強度,RSA密鑰至少為500位長,一般推薦使用1024位。
RSA算法是R.Rivest、A.Shamir和L.Adleman于1977年在美國麻省理工學院開發(fā),于1978年首次公布。
RSA公鑰密碼算法是目前網(wǎng)絡上進行保密通信和數(shù)字簽名的最有效的安全算法之一。RSA算法的安全性基于數(shù)論中大素數(shù)分解的困難性,所以,RSA需采用足夠大的整數(shù)。因子分解越困難,密碼就越難以破譯,加密強度就越高。?
其算法如下:
A.?選擇兩質(zhì)數(shù)p、q
B.?計算n?=?p?*?q
C.?計算n的歐拉函數(shù)Φ(n)?=?(p?-?1)(q?-?1)
D.?選擇整數(shù)e,使e與Φ(n)互質(zhì),且1?<?e?<?Φ(n)
E.?計算d,使d?*?e?=?1?mod?Φ(n)
其中,公鑰KU={e,?n},私鑰KR={d,?n}。
加密/解密過程:
利用RSA加密,首先需將明文數(shù)字化,取長度小于log2n位的數(shù)字作為明文塊。
對于明文塊M和密文塊C,加/解密的形式如下:
加密:?C?=?Me?mod?n
解密:?M?=?Cd?mod?n?=?(Me)d?mod?n?=?Med?mod?n
RSA的安全性基于大數(shù)分解質(zhì)因子的困難性。因為若n被分解為n?=?p?*?q,則Φ(n)、e、d可依次求得。目前,因式分解速度最快的方法的時間復雜性為exp(sqrt(ln(n)lnln(n)))。統(tǒng)計數(shù)據(jù)表明,在重要應用中,使用512位的密鑰已不安全,需要采用1024位的密鑰。
(2)DSA算法
DSA(Digital?Signature?Algorithm,數(shù)字簽名算法,用作數(shù)字簽名標準的一部分),它是另一種公開密鑰算法,它不能用作加密,只用作數(shù)字簽名。DSA使用公開密鑰,為接受者驗證數(shù)據(jù)的完整性和數(shù)據(jù)發(fā)送者的身份。它也可用于由第三方去確定簽名和所簽數(shù)據(jù)的真實性。DSA算法的安全性基于解離散對數(shù)的困難性,這類簽字標準具有較大的兼容性和適用性,成為網(wǎng)絡安全體系的基本構(gòu)件之一。??
DSA簽名算法中用到了以下參數(shù):?
p是L位長的素數(shù),其中L從512到1024且是64的倍數(shù)。?
q是160位長且與p-1互素的因子?,其中h是小于p-1并且滿足?大于1的任意數(shù)。??
x是小于q的數(shù)。??
另外,算法使用一個單向散列函數(shù)H(m)。標準指定了安全散列算法(SHA)。三個參數(shù)p,q和g是公開的,且可以被網(wǎng)絡中所有的用戶公有。私人密鑰是x,公開密鑰是y。??
對消息m簽名時:??
(1)?發(fā)送者產(chǎn)生一個小于q的隨機數(shù)k。??
(2)?發(fā)送者產(chǎn)生:?
r和s就是發(fā)送者的簽名,發(fā)送者將它們發(fā)送給接受者。??
(3)?接受者通過計算來驗證簽名:
如果v=r,則簽名有效。?
(3)Diffie-Hellman密鑰交換
DH算法是W.Diffie和M.Hellman提出的。此算法是最早的公鑰算法。它實質(zhì)是一個通信雙方進行密鑰協(xié)定的協(xié)議:兩個實體中的任何一個使用自己的私鑰和另一實體的公鑰,得到一個對稱密鑰,這一對稱密鑰其它實體都計算不出來。DH算法的安全性基于有限域上計算離散對數(shù)的困難性。離散對數(shù)的研究現(xiàn)狀表明:所使用的DH密鑰至少需要1024位,才能保證有足夠的中、長期安全。
(4)?橢圓曲線密碼體制(ECC)
1985年,N.?Koblitz和V.?Miller分別獨立提出了橢圓曲線密碼體制(ECC),其依據(jù)就是定義在橢圓曲線點群上的離散對數(shù)問題的難解性。?
為了用橢圓曲線構(gòu)造密碼系統(tǒng),首先需要找到一個單向陷門函數(shù),橢圓曲線上的數(shù)量乘就是這樣的單向陷門函數(shù)。
橢圓曲線的數(shù)量乘是這樣定義的:設E為域K上的橢圓曲線,G為E上的一點,這個點被一個正整數(shù)k相乘的乘法定義為?k個G相加,因而有
kG?=?G?+?G?+?…?+?G???????(共有k個G)
若存在橢圓曲線上的另一點N?≠?G,滿足方程kG?=?N。容易看出,給定k和G,計算N相對容易。而給定N和G,計算k?=?logG?N相對困難。這就是橢圓曲線離散對數(shù)問題。
離散對數(shù)求解是非常困難的。橢圓曲線離散對數(shù)問題比有限域上的離散對數(shù)問題更難求解。對于有理點數(shù)有大素數(shù)因子的橢圓離散對數(shù)問題,目前還沒有有效的攻擊方法。
1.4?回調(diào)函數(shù)
?Openssl中大量用到了回調(diào)函數(shù)。回調(diào)函數(shù)一般定義在數(shù)據(jù)結(jié)構(gòu)中,是一個函數(shù)指針。通過回調(diào)函數(shù),客戶可以自行編寫函數(shù),讓openssl函數(shù)來調(diào)用它,即用戶調(diào)用openssl提供的函數(shù),openssl函數(shù)再回調(diào)用戶提供的函數(shù)。這樣方便了用戶對openssl函數(shù)操作的控制。在openssl實現(xiàn)函數(shù)中,它一般會實現(xiàn)一個默認的函數(shù)來進行處理,如果用戶不設置回調(diào)函數(shù),則采用它默認的函數(shù)。
?回調(diào)函數(shù)舉例:
頭文件:
#ifndef?RANDOM_H
#define?RANDOM_H?1
typedef?int?*callback_random(char?*random,int?len);
void????set_callback(callback_random?*cb);
int?????genrate_random(char?*random,int?len);
#endif
源代碼:
#include?"random.h"
#include?<stdio.h>
callback_random?*cb_rand=NULL;
static?int?default_random(char?*random,int?len
{
????????memset(random,0x01,len);
????????return?0; }
void????set_callback(callback_random?*cb)
{
????????cb_rand=cb;
}
int?????genrate_random(char?*random,int?len) {
????????if(cb_rand==NULL)
????????????????return?default_random(random,len);
????????else
????????????????return?cb_rand(random,len);
????????return?0;
}
測試代碼:
#include?"random.h"
static?int?my_rand(char?*rand,int?len)
{
????????memset(rand,0x02,len);
????????return?0;
}
int?????main()
{
????????char????random[10];
????????int?????ret;
set_callback(my_rand);
????????ret=genrate_random(random,10);
????????return?0;
}
本例子用來生產(chǎn)簡單的隨機數(shù),如果用戶提供了生成隨機數(shù)回調(diào)函數(shù),則生成隨機數(shù)采用用戶的方法,否則采用默認的方法。
總結(jié)
以上是生活随笔為你收集整理的《openssl编程》之基础知识的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IOCP不可忽视的细节
- 下一篇: 《openssl编程》之openssl简