OpenSSL
使用指南
http://www.fs2you.com/files/5b43b3b0-5e3d-11dd-9b38-0019d11a795f/?
?
目錄
?? 介紹
?? 編譯
?? 運行 OpenSSL.exe
?? 算法編程 API
4.1 對稱算法
4.1.1 DES
4.1.2 A ES
4.1.3 RC4
4.1.4 EVP_
4.2 公鑰算法
4.3 Hash 算法
4.4 隨機數算法
?? SSL 協議編程 API
?? CA 和證書
?? ?
?? 參考網址
?? ?
?? 示例程序
?? ?
?
?? 介紹
OpenSSL 是使用非常廣泛的 SSL 的開源實現。由于其中實現了為 SSL 所用的各種加密算法,因此 OpenSSL 也是被廣泛使用的加密函數庫。
1.1 SSL
SSL(Secure Socket Layer) 安全協議是由 Netscape 公司首先提出,最初用在保護 Navigator 瀏覽器和
Web 服務器之間的 HTTP 通信 ( 即 HTTPS) 。后來 SSL 協議成為傳輸層安全通信事實上的標準,并被 IETF 吸收改進為
TLS(Transport Layer Security) 協議。
SSL/TLS 協議位于 TCP 協議和應用層協議之間,為傳輸雙方提供認證、加密和完整性保護等安全服務。 SSL 作為一個協議框架,通信雙方可以選用合適的對稱算法、公鑰算法、 MAC 算法等密碼算法實現安全服務。
1.2 OpenSSL
OpenSSL 是著名的 SSL 的開源實現,是用 C 語言實現的。
OpenSSL 的前身是 SSLeay ,一個由 Eric Young 開發的 SSL 的開源實現,支持 SSLv2/v3 和 TLSv1 。
伴隨著 SSL 協議的普及應用, OpenSSL 被廣泛應用在基于 TCP/Socket 的網絡程序中,尤其是 OpenSSL 和 Apache 相結合,是很多電子商務網站服務器的典型配置。
?
?? 編譯和安裝 OpenSSL
OpenSSL 開放源代碼,這對學習、分析 SSL 和各種密碼算法提供了機會,也便于在上面進一步開發。
2.1
獲得 OpenSSL
到 OpenSSL 的網站即可下載當前版本的 OpenSSL 源代碼壓縮包。
當前版本 openssl- 0.9.8 .tar.gz ,只有 3M 多,比較精簡。解壓縮后得到一個目錄 openssl-0.9.8
,共有約 1800 個文件, 15M 。其中 crypto 子目錄中是眾多密碼算法實現, ssl 子目錄中是 SSL 協議的實現。
在 Linux 中解壓縮:
$tar zxf openssl- 0.9.8 .tar.gz
在 Windows 中可以使用 winzip 或 winrar 。
2.2
編譯工具
編譯 OpenSSL 需要 Perl 和 C 編譯器。在 Windows 下如果要用加密算法的匯編代碼實現,還需要 masm 或 nasm 匯編器。 ( 匯編代碼可以比 C 代碼顯著提高密碼運算速度 )
Perl 在 Windows 下推薦使用 Active Perl 。
C 編譯器可以使用 gcc 。在 W indows 下可以使用 Visual C 編譯器。
匯編器推薦使用 nasm 。
這些工具所在目錄必須加入到 PATH 環境變量中去。
2.3
編譯和安裝步驟
查看 readme 是個好習慣。從 readme 了解到需要進一步查看 INSTALL 和 INSTALL.W32 文件。
在 Windows 中:
>perl Configure VC-WIN32
>ms\do_nasm ( 如果不使用匯編代碼實現,則可 >ms\do_ms)
>nmake -f ms\ntdll.mak
>cd out32dll
>..\ms\test
編譯結果得到頭文件、鏈接庫、運行庫和 openssl.exe 工具。頭文件位于 ./inc32 或者 ./inculde 目錄,有一個
openssl 子目錄,內有幾十個 .h 文件。鏈接庫即 ./out32dll 目錄中的 libeay32.lib 和 ssleay32.lib
,分別是密碼算法相關的和 ssl 協議相關的。運行庫是 ./out32dll 目錄中的 libeay32.dll 和 ssleay32.dll
,和鏈接庫相對應。在 ./out32dll 中還有一個工具 openssl.exe ,可以直接用來測試性能、產生 RSA
密鑰、加解密文件,甚至可以用來維護一個測試用的 CA 。
在 Linux 中的編譯和安裝步驟較簡單 :
$./config
$make
$make test
$make install
在 Linux 下,頭文件、庫文件、工具都已被安裝放到了合適的位置。庫文件是 .a 或 .so 格式。
?
?? 使用 OpenSSL.exe
使用 OpenSSL.exe(Linux 中可執行文件名是 openssl) 可以做很多工作,是一個很好的測試或調試工具。
3.1
版本和編譯參數
顯示版本和編譯參數: >openssl version -a
3.2
支持的子命令、密碼算法
查看支持的子命令: >openssl ?
SSL 密碼組合列表: >openssl ciphers
3.3
測試密碼算法速度
測試所有算法速度: >openssl speed
測試 RSA 速度: >openssl speed rsa
測試 DES 速度: >openssl speed des
3.4 RSA
密鑰操作
產生 RSA 密鑰對: >openssl genrsa -out 1.key 1024
取出 RSA 公鑰: >openssl rsa -in 1.key -pubout -out 1.pubkey
3.5
加密文件
加密文件: >openssl enc -e -rc4 -in 1.key -out 1.key.enc
解密文件: >openssl enc -d -rc4 -in 1.key.enc -out 1.key.dec
3.6
計算 Hash 值
計算文件的 MD5 值: >openssl md5 < 1.key
計算文件的 SHA1 值: >openssl sha1 < 1.key
?
?? 算法編程 API
OpenSSL 中支持眾多的密碼算法,并提供了很好的封裝和接口。密碼算法主要分為如下幾類:對稱算法、公鑰算法、散列算法、隨機數產生算法等。
OpenSSL 的目標是實現安全協議。其中相關協議和標準包括: SSL/TLS 、 PKCS#1 、 PCKS#10 、 X.509 、 PEM 、 OCSP 等。
4.1
對稱算法接口
OpenSSL 中實現的對稱算法太多,舉三個例子: DES 、 AES 、 RC4 。
4.1.1
DES
DES 加密算法是分組算法。 DES 的基本操作是把 64 比特明文在 56 比特密鑰指引下加密成 64 比特密文。在實際使用中把密鑰看作 64 比特可以更方便。
DES ( IN , KEY ) = OUT
(1) DES ECB
模式
在 OpenSSL 中 ECB 操作模式對應的函數是 DES_ecb_encrypt() ,該函數把一個 8 字節明文分組 input
加密成為一個 8 字節密文分組 output 。參數中密鑰結構 ks 是用函數 DES_set_key() 準備好的,而密鑰 key
是用隨機數算法產生的 64 個隨機比特。參數 enc 指示是加密還是解密。該函數每次只加密一個分組,因此用來加密很多數據時不方便使用。
void DES_ecb_encrypt(const_DES_cblock *input,DES_cblock *output, DES_key_schedule *ks,int enc);
int DES_set_key(const_DES_cblock *key,DES_key_schedule *schedule);
(2) DES CBC
模式
DES 算法 CBC 操作模式加解密函數是 DES_ncbc_encrypt() 。參數 length 指示輸入字節長度。如果長度不是 8 字節的倍數,則會被用 0 填充到 8 字節倍數。因此,輸出可能比 length 長,而且必然是 8 字節的倍數。
void DES_ncbc_encrypt(const unsigned char *input,unsigned char
*output, long length, DES_key_schedule *schedule, DES_cblock *ivec, int
enc);
(3) DES CFB
模式
DES 算法 CFB 操作模式加解密函數是 DES_cfb_encrypt() 。參數 length 指示輸入字節長度。參數
numbits 則指示了 CFB 每次循環加密多少明文比特,也即密文反饋的比特數目。 ivec 是初始向量,被看做第 0
個密文分組,是不用保密但應隨機取值的 8 個字節。如果在一次會話中數次調用 DES_cfb_encrypt() ,則應該記憶 ivec 。由于
CFB 模式中每次 DES 基本操作只加密 numbits 比特明文,因此如果 numbits 太小則效率太低。
void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int
numbits, long length, DES_key_schedule *schedule, DES_cblock *ivec, int
enc);
另有一個 numbit 是 64 比特的版本,既高效又沒有填充的麻煩,推薦使用。 num 中的返回值指示了 ivec 中的狀態,是和下次調用銜接的。
void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out,
long length, DES_key_schedule *schedule, DES_cblock *ivec, int *num, int
enc) ;
(4) DES OFB
模式
OFB 和 CFB 類似,也有兩個函數,用法一樣。
void DES_ofb_encrypt(const unsigned char *in,unsigned char *out,int
numbits,long length,DES_key_schedule *schedule,DES_cblock *ivec);
void DES_ofb64_encrypt(const unsigned char *in,unsigned char
*out,long length,DES_key_schedule *schedule,DES_cblock *ivec,int *num);
(5) DES
函數示例程序
見附件 A.1 。
4.1.2 A
ES
AES 加密算法是分組算法。典型參數的 AES 的基本操作是把 128 比特明文在 128 比特密鑰指引下加密成 128 比特密文。
AES ( IN , KEY ) = OUT
OpenSSL 中關于 AES 的函數名和參數接口和 DES 的雷同。相關函數名如下 ( 參數略 ) 。
int AES_set_encrypt_key();
int AES_set_decrypt_key();
void AES_ecb_encrypt();
void AES_cbc_encrypt();
void AES_cfb128_encrypt();
void AES_ofb128_encrypt();
AES 示例程序見附件 A.2 。
4.1.3
RC4
RC4 密碼算法是流算法,也叫序列算法。流算法是從密鑰作為種子產生密鑰流,明文比特流和密鑰流異或即加密。 RC4 算法由于算法簡潔,速度極快,密鑰長度可變,而且也沒有填充的麻煩,因此在很多場合值得大力推薦。
OpenSSL 中 RC4 算法有兩個函數 : RC4_set_key() 設置密鑰, RC4() 加解密。可以把 RC4 看作異或,因此加密兩次即解密。
void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata, unsigned char *outdata);
RC4 示例程序見附件 A.3 。
例子 A.3.(1) 是利用 OpenSSL 動態庫函數。例子 A.3.(2) 是把 RC4 的實現代碼從 OpenSSL 中分離出來的。例子 A.3.(3) 是另一個演示實現。
4.2
公鑰算法
OpenSSL 中實現了 RSA 、 DSA 、 ECDSA 等公鑰算法。
4.2.1
RSA
RSA 是分組算法,典型的密鑰模長度 1024 比特時,分組即是 1024 比特,即 128 字節。
(1) RSA
密鑰
RSA 密鑰產生函數 RSA_generate_key() ,需要指定模長比特數 bits 和公鑰指數 e 。另外兩個參數為 NULL 即可。
RSA * RSA_generate_key(int bits, unsigned long e, void (*callback) (int,int,void *),void *cb_arg);
如果從文件中讀取密鑰,可使用函數 PEM_read_bio_PrivateKey()/ PEM_read_bio_PUBKEY(); EVP_PKEY 中包含一個 RSA 結構,可以引用。
EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u);
(2) RSA
加密解密
RSA 加密函數 RSA_public_encrypt() 使用公鑰部分,解密函數 RSA_private_decrypt()
使用私鑰。填充方式常用的有兩種 RSA_PKCS1_PADDING 和 RSA_PKCS1_OAEP_PADDING 。出錯時返回 -1
。輸入必須比 RSA 鑰模長短至少 11 個字節(在 RSA_PKCS1_PADDING 時?)。輸出長度等于 RSA 鑰的模長。
int RSA_public_encrypt(int flen, const unsigned char *from,unsigned char *to, RSA *rsa,int padding);
int RSA_private_decrypt(int flen, const unsigned char *from,unsigned char *to, RSA *rsa,int padding);
(3)
簽名和驗證
簽名使用私鑰,驗證使用公鑰。 RSA 簽名是把被簽署消息的散列值編碼后用私鑰加密,因此函數中參數 type 用來指示散列函數的類型,一般是 NID_md5 或 NID_sha1 。正確情況下返回 0 。
int RSA_sign(int type, const unsigned char *m, unsigned int m_length, unsigned char *sigret, unsigned int *siglen, RSA *rsa);
int RSA_verify(int type, const unsigned char *m, unsigned int m_length, unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
(4) RSA
函數示例程序
RSA 示例程序見附件 A.4 。
例子 A.4.(1) 是加密解密例子。例子 A.4.(2) 是簽名驗證例子。
4.2.2
DSA
( TOBE )
4.2.2
ECDSA
( or NOT TOBE )
4.3 Hash
算法
Hash 算法舉 MD5 和 SHA1 兩個例子。 Hash 算法重復接收用戶輸入,直到最后一次結束時輸出散列結果。
4.3.1
MD5
MD5 算法輸出的散列值是 16 字節。
int MD5_Init(MD5_CTX *c);
int MD5_Update(MD5_CTX *c, const void *data, size_t len);
int MD5_Final(unsigned char *md, MD5_CTX *c);
4.3.2
SHA1
SHA1 算法輸出的散列值是 20 字節。
int SHA1_Init(SHA_CTX *c);
int SHA1_Update(SHA_CTX *c, const void *data, size_t len);
int SHA1_Final(unsigned char *md, SHA_CTX *c);
4.3.3
MD5
例子
MD5 示例程序見附件 A.5 。
md5sum 這是一個實用小工具,可以計算一個文件的 MD5 值。
4.4
隨機數算法
隨機性是密碼安全的基石。為了產生安全的偽隨機數,必須有好的隨機因素作為種子。 OpenSSL 在內部做了努力,但是仍建議在實用隨機數產生函數之前添加隨機因素。
函數 RAND_add() 可以添加隨機因素到內部狀態中去。然后,即可以使用 RAND_bytes() 獲得隨機數。
void RAND_add(const void *buf,int num,double entropy);
int RAND_bytes(unsigned char *buf,int num);
?
?? SSL 協議編程 API
5.1
客戶端
5.2
服務器端
5.3 SSL
示例程序
參見 A.6 。
?
?? CA 和證書
6.1 OpenSSL
中 CA 的配置
6.2
配置示例
參見 A.7.(1) 。
6.3
證書解析
6.4
解析示例程序
參見 A.7.(2) 。
?
?? ?
?
?? 參考網址
SSL 3.0 Specification
http://www.netscape.com/eng/ssl3/
Transp ort Layer Security (tls) Charter
http://www.ietf.org/html.charters/tls-charter.html
OpenSSL: The Open Source toolkit for SSL/TLS
http://www.openssl.org/
SSLeay
http://www2.psy.uq.edu.au/~ftp/Crypto/
OpenSSL 中文論壇
http://openssl.cn/
Perl
http://www.cpan.org/src/README.html
http://www.activestate.com/Products/ActivePerl/
NASM
http://www.perl.com/
studio
?
?? ?
?
?? 示例程序
注 : 此嵌入的文件對象可以被拖放到磁盤目錄中去。
?? DES 示例程序
?? AES 示例程序
?? RC4 示例程序
( 1 ). ( 2 ). ( 3 )
?? RSA 示例程序
( 1 ). ( 2 ).
?? Hash 算法示例程序
?? SSL 示例程序
?? CA 配置示例和證書解析示例程序
(1). (2).
?? ?
?? ?
引自:http://www.cnblogs.com/ahuo/archive/2008/07/30/1256820.html