openssl之evp系列之6---evp_encrypt系列函式程式設計架構及例子
---根據openssl doc/crypto/evp_encryptinit.pod和doc/ssleay.txt cipher.doc部分翻譯和自己的理解寫成
在前面的兩篇文章,已經對evp_encrypt*...*系列函式做了詳細的介紹,本章將說明該系列函式通用的應用架構,並舉幾個函式應用例子。
【應用架構】
一般來說,evp_encrypt*...*系列函式的應用架構如下所描述(假設加密演算法為3des):
1.定義一些必須的變數
char key[evp_max_key_length];
char iv[evp_max_iv_length];
evp_cipher_ctx ctx;
unsigned char out[512+8];
int outl;
2.給變數key和iv賦值,這裡使用了函式evp_bytestokey,該函式從輸入密碼產生了金鑰key和初始化向量iv,該函式將在後面做介紹。如果可以有別的辦法設定key和iv,該函式的呼叫不是必須的
evp_bytestokey(evp_des_ede3_cbc,evp_md5,null,passwd,strlen(passwd),key,iv);
3.初始加密演算法結構evp_cipher_ctx
evp_encryptinit_ex(&ctx, evp_des_ede3_cbc(), null, key, iv);
4.進行資料的加密操作
while (....)
一般來說採用了迴圈的結構進行處理,每次迴圈加密資料為512位元組,密文輸出到out,out和int應該是指向不相同的記憶體的。
5.結束加密,輸出最後的一段512位元組的資料
evp_encryptfinal_ex(&ctx, out, &outl)
該函式會進行加密的檢測,如果加密過程有誤,一般會檢查出來。
說明:加密跟上述過程是一樣的,只不過要使用evp_decrypt*...*系列函式。
【例子】
1.取得演算法rc5使用的迴圈次數(round)
int nrounds;
evp_cipher_ctx_ctrl(ctx, evp_ctrl_get_rc5_rounds, 0, &nrounds);
2.取得演算法rc2的有效金鑰長度
int key_bits;
evp_cipher_ctx_ctrl(ctx, evp_ctrl_get_rc2_key_bits, 0, &key_bits);
3.設定演算法rc5使用的迴圈次數(round)
int nrounds;
evp_cipher_ctx_ctrl(ctx, evp_ctrl_set_rc5_rounds, nrounds, null);
4.設定演算法rc2的有效金鑰長度
int key_bits;
evp_cipher_ctx_ctrl(ctx, evp_ctrl_set_rc2_key_bits, key_bits, null);
5.使用blowfish演算法加密乙個字串
int do_crypt(char *outfile)
;unsigned char iv = ;
char intext = "some crypto text";
evp_cipher_ctx ctx;
file *out;
evp_cipher_ctx_init(&ctx);
evp_encryptinit_ex(&ctx, evp_bf_cbc(), null, key, iv);
if(!evp_encryptupdate(&ctx, outbuf, &outlen, intext, strlen(intext)))
//注意,傳入給下面函式的輸出快取引數必須注意不能覆蓋了原來的加密輸出的資料
if(!evp_encryptfinal_ex(&ctx, outbuf + outlen, &tmplen))
outlen += tmplen;
evp_cipher_ctx_cleanup(&ctx);
//注意,儲存到檔案的時候要使用二進位制模式開啟檔案,因為密文資料是二進位制的,而且,不能採用strlen函式,因為密文字串不是以null(0)為結束的字串
out = fopen(outfile, "wb");
fwrite(outbuf, 1, outlen, out);
fclose(out);
return 1;
}上面舉的例子加密的密文可以使用openssl提供的應用程式cipher.exe來解密,命令如下:
openssl bf -in cipher.bin -k 000102030405060708090a0b0c0d0e0f -iv 0102030405060708 -d
6.使用檔案i/o和80位金鑰rc2演算法的通用加密解密函式例項,該函式可以進行加密,也可以進行解密,由引數do_encrypt決定,該引數為1時則執行加密,為0時則執行解密。
int do_crypt(file *in, file *out, int do_encrypt)
fwrite(outbuf, 1, outlen, out);
}if(!evp_cipherfinal_ex(&ctx, outbuf, &outlen))
fwrite(outbuf, 1, outlen, out);
evp_cipher_ctx_cleanup(&ctx);
return 1;
靜態聯編(函式過載)和動態聯編(虛函式)
一 靜態聯編 定義 由於函式過載,編譯器必須檢視函式引數以及函式名就能確定使用哪個函式 這種c c 編譯器可以在編譯過程中完成的聯編,被稱為靜態聯編 函式過載 在同一作用域中,可以有一組具有相同函式名,不同引數列表的函式,這組函式被稱為過載函式 二 動態聯編 定義 使用哪個函式是不能在編譯時確定的,...
虛函式與聯編
虛函式必須是基類的非靜態成員函式,其訪問許可權可以是private或protected或public,在基類的類定義中定義虛函式的一般形式。在某基類中宣告為 virtual 並在乙個或多個派生類中被重新定義的成員函式,實現多型性。語法 virtual 函式返回型別 函式名 參數列 虛函式必須是基類的...
虛函式 1 靜態聯編與動態聯編,引入虛函式
在實際開發工作中,為提高 的重用性,編寫通用的功能模組,往往需要設計處理幾種不同物件的通用程式,如示例2.1所示。示例清單2.1 include stdio.h include stdlib.h 定義函式指標型別displayinteger,指向返回值為void,引數列表為 const int 的函...