• 沒有找到結果。

SSL是Secure Sockets Layer的縮寫。它是一個在 Internet 上進行安全通訊 的標準,在封包加密的機制上我們選用一個Open Source的加密套件OpenSSL [9]

加密模組,這是一套開放原始碼的SSL套件,其函式庫是以C語言所寫成,實作了 基本的傳輸層資料加密功能。此軟體是以Eric Young以及Tim Hudson兩人所寫的 SSLeay [10] 為基礎所發展的。支援多種對稱式DES、IDEA、RC2、RC4、RC5、

Blowfish、CAST,與非對稱式RSA、DH、DSA的加密演算法,並且在UNIX系統下 可以很方便的安裝與使用,例如在我們主要實作的系統 ubuntu Linux 下只要使

用指令 ” apt-get install libssl-dev” 就可以利用apt套件來安裝編譯程式時所需 要的OpenSSL加密模組。

OpenSSL 將各種加密演算法各自獨特地方封裝在內部,對外則使用了統一 的呼叫介面,因此外部應用只需指定使用何種加密演算法,就可以用相同方法呼 叫加解密函數而不用考慮其內部實作方式的差異。EVP 系列函數就是 OpenSSL 統一格式的interface,定義包含在 evp.h 裡面,這是一系列封裝了 OpenSSL 加 密庫裡面所有演算法的函數。透過這樣的統一封裝,使得只需要在初始化參數的 時候做少許的改變,就可以使用相同程式呼叫格式,但採用不同加密演算法進行 資料的加密和解密。

實際使用的情況以對稱式加密演算法Blowfish 為例,只要在 C/C++的原始 碼最前面引用Blowfish 與 EVP 的標頭檔:

#include <openssl/blowfish.h>

#include <openssl/evp.h>

與宣告加解密所需要用到的key 與 initial vector。然後在 main function 開頭初 始key 與 schedule,其中在 EVP_BytesToKey () 例子裡,指定好要給哪種演算 法(EVP_bf_cbc)所使用的金鑰,產生金鑰雜湊的演算法(EVB_md5),亂數種 子(範例中給一個空的值NULL),最後是一個字串 "plaslab.cis.nctu.edu.tw",

與其長度,讓系統產生加密所需的金鑰。

unsigned char key[16];

unsigned char iv[8];

char *str = “plaslab.cis.nctu.edu.tw”;

EVP_BytesToKey(EVP_bf_cbc,EVP_md5,NULL,str,strlen(str),key,iv);

加密與解密的流程是一樣的,差別在第2 到第 4 步驟所呼叫的加密/解密函數不 一樣,以下是加密函數詳細流程:

1. EVP_CIPHER_CTX_init

初始化一個 EVP_CIPHER_CTX 資料結構,只有初始化後該資料結構才能在下面 介紹的函數中使用。

2. EVP_EncryptInit (解密則是呼叫 EVP_DecryptInit)

設置並初始化EVP_CIPHER_CTX 資料結構。其中,參數 ctx 必須在調用本函數之 前已經進行了初始化。參數 type 通常通過函數類型來提供參數,例如下面所使 用的EVP_bf_cbc () 函數形式。最後是加密金鑰 key,與初始化向量 iv。

3. EVP_EncryptUpdate (解密則是呼叫 EVP_DecryptUpdate)

對in 指標所指長度為 ilen 的字串做加密,將結果儲存在 outbuf 中,當輸入資料 超過該加密演算法block size 的時候,本函數會自動處理。

4. EVP_EncryptFinal (解密則是呼叫 EVP_DecryptFinal)

因為加密演算法必須以固定大小block 為單位(例如這裡的 Blowfish 為 64 bits)

做加密,若遇到最後面除不盡剩下來的資料做padding 特別處理。

5. EVP_CIPHER_CTX_cleanup

清除一個 EVP_CIPHER_CTX 結構中所有資料,並釋放該結構佔用的所有記憶體 空間,這樣可以避免一些敏感訊息遺留在記憶體中造成安全上的疑慮。

以下是使用Blowfish 演算法實作加密函數的範例:

int encrypt(int ilen,unsigned char *in,int *olen,unsigned char *out) {

int tlen, n;

unsigned char outbuf[OP_SIZE];

EVP_CIPHER_CTX ctx;

// 初始化加密結構,給之後的函數使用 EVP_CIPHER_CTX_init (&ctx);

// 設定加密的各項參數

EVP_EncryptInit(&ctx, EVP_bf_cbc (), key, iv);

// in指標所指的資料做加密,結果存在outbuf中 EVP_EncryptUpdate(&ctx, outbuf, olen, in, ilen);

// 處理剩餘block的資料

EVP_EncryptFinal(&ctx, outbuf + *olen, &tlen);

// 計算加密後真正資料的長度,並寫回output指標 *olen += tlen;

memcpy(out, outbuf, *olen);

// 清除加密結構,去掉存在記憶體中可能的對安全造成威脅資訊 EVP_CIPHER_CTX_cleanup (&ctx);

return 1;

}

相關文件