多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > 互聯網 > 源碼方式向openssl中添加新算法完整詳細步驟(示例:摘要算法SM3)【非engine方式】

源碼方式向openssl中添加新算法完整詳細步驟(示例:摘要算法SM3)【非engine方式】

來源:程序員人生   發布時間:2014-09-17 07:19:16 閱讀次數:5866次

openssl簡介

openssl是一個功能豐富且自包含的開源安全工具箱。它提供的主要功能有:SSL協議實現(包括SSLv2、SSLv3和TLSv1)、大量軟算法(對稱/非對稱/摘要)、大數運算、非對稱算法密鑰生成、ASN.1編解碼庫、證書請求(PKCS10)編解碼、數字證書編解碼、CRL編解碼、OCSP協議、數字證書驗證、PKCS7標準實現和PKCS12個人數字證書格式實現等功能。

openssl采用C語言作為開發語言,這使得它具有優秀的跨平臺性能。openssl支持Linux、UNIX、windows、Mac等平臺。openssl目前最新的版本是openssl-1.0.1i。

更多的相關知識請參閱鋪天蓋地的各種官方非官方文檔。今天來實現怎樣將一個新算法添加進openssl中。

問題描述

openssl中雖然集成了很多經典算法,對稱算法、非對稱算法、摘要算法等等,但有時候我們需要用到自定義的算法,比如要實現一個自定義的摘要算法,需要借助openssl帶的大數庫來實現,同時又希望將自己實現的算法封裝到openssl里面,以便統一調用或者方便項目改造和替換。最具現實意義的案例就是國密SM2等的改造。本例將用國密中的摘要算法SM3作為添加對象,在windows下面進行編譯調試,僅描述添加步驟,所以本文的前提是已經完成了基于openssl大數庫的SM3的c語言實現。本文僅供依葫蘆畫瓢,要理解原理請自行查閱別的資料或者自己解讀源碼,或者等我的下一篇文章。

具體步驟

一、準備工作

1、  下載openssl源碼,openssl目前最新的版本是openssl-1.0.1i。下載地址:

2、  sm3的c語言實現。

3、  windows下perl、vc的安裝配置。

4、  熟悉openssl的編譯過程。

二、SM3代碼改造【這個步驟涉及到的文件全部新建,存放目錄關系如圖】

1、  涉及到的文件7個:


1、  【新建文件】sm3.h

這是最重要的一個頭文件,里面定義了算法可以導出的算法,也就是里面聲明的每一個函數最后都會生成對應的libeay.num(將在第五章中具體講),能夠導出到dll中供外部調用。幾個主要的聲明如下:

定義sm3的摘要長度:

#define SM3_DIGEST_LENGTH 32    /* sm3 摘要長度為256位 32字節,md5的摘要長度128位 not sure*/

定義SM3_CTX,這個結構其實就是對應evp封裝中EVP_MD_CTX的md_data:

typedef struct SM3state_st { unsigned long long total_length; unsigned char message_buffer[64]; size_t message_buffer_position; size_t V_i[8]; size_t V_i_1[8]; size_t T_j[64]; } SM3_CTX;

聲明函數,包括init、update、final,這幾個函數會在封裝的時候被內部調用,當然在dll中導出了也可以外部調用:

int SM3_Init(SM3_CTX*c); intSM3_Update(SM3_CTX *c, const void *data, size_t len); intSM3_Final(unsigned char *md, SM3_CTX *c); unsignedchar *SM3(unsigned char *d, size_t n, unsigned char *md);

2、  【新建文件】sm3_locl.h

這個頭文件中包含一些要用到的宏定義。主要定義了本算法實現中需要用到的內部函數,不能被導出到dll中供外部調用。

宏定義:

#ifndefROTATE #defineROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) #endif #define EE(b,c,d) ((b & c) | ((~ b) & d)) #define FF(b,c,d) ((((c)^ (d)) & (b)) ^ (d)) #define GG(b,c,d) (((b)& (c)) | ((b) & (d)) | ((c) & (d))) #define HH(b,c,d) ((b)^ (c) ^ (d)) #define HH1(a) (a^ (ROTATE(a, 9)) ^ (ROTATE(a, 17))) #define HH2(a) (a^ (ROTATE(a, 15)) ^ (ROTATE(a, 23))) 內部函數: voidinit_T_j(size_t *T_j); voidinit_V_i(size_t *V_i); voidCF(size_t *T_j,size_t *V_i, unsigned char *B_i, size_t *V_i_1);

3、  【新建文件】sm3_dgst.c

實現sm3.h和sm3_locl中聲明的函數,除了函數SM3(將在sm3_one.c中實現)。

4、  【新建文件】sm3_one.c

實現sm3.h中聲明的函數SM3。

5、  【新建文件】sm3.c

實現對文件的摘要,如用在openssl作為命令行工具,文件名和摘要算法名作為選項參數實現使用算法對文件進行摘要。

6、  【新建文件】sm3test.c

算法的test文件。

7、  【新建文件】Makefile

編譯的Makefile文件。里面描述在編譯的時候以上的幾個文件的角色、編譯過程、依賴關系等。

三、EVP封裝相關代碼

1、  涉及到的文件4個:

2、  【手動修改】evp.h

evp在openssl里面的主要做的是封裝的事情,因此首先在evp.h頭文件中添加新算法sm3:

#ifndef OPENSSL_NO_SM3 const EVP_MD *EVP_sm3(void); #endif


說明:EVP_sm3()函數將返回返回一個sm3的EVP_MD的結構,這個結構以及EVP_sm3()函數都在m_sm3.c中定義。

3、  【新建文件】m_sm3.c

這是放在EVP目錄中關于新算法的一個重要文件,定義sm3的EVP_MD結構,EVP_MD結構原型在evp.h中:


sm3的EVP_MD結構:


static const EVP_MD sm3_md= { NID_sm3,//這個需要定義了OID之后生成,這個步驟在第四章。 NID_sm3WithRSAEncryption,//這個地方sm3WithRSA只做示例 SM3_DIGEST_LENGTH,//SM3的摘要長度,在sm3.h中定義 0, //flag init, //結構中的init函數,指向自己聲明在sm3.h中的SM3_Init update,//同上 final,//同上 NULL, NULL, EVP_PKEY_RSA_method,//同上,只做示例 SM3_CBLOCK, //在sm3.h中聲明 sizeof(EVP_MD *)+sizeof(SM3_CTX), };

4、  【手動修改】c_alld.c

openssl的算法封裝之后使用時需要加載算法,實現SM3的添加:

#ifndefOPENSSL_NO_SM3 EVP_add_digest(EVP_sm3()); #endif


5、  【手動修改】Makefile

將編譯時候的LIBSRC、LIBOBJ中加入SM3新算法,并且添加sm3各種頭文件的依賴關系。




四、OID生成

1、  涉及到的文件7個:

2、  【手動修改】objects.txt

添加sm3的OID,特別說明:此處僅作示例,sm3的實際OID是:

rsadsi 2 12 :SM3 : sm3

添加sm3WithRSAEncryption,這個是對應PKCS1的,只是為了讓sm3的EVP_MD結構有值填充,實際添加sm3的本意不用于RSA,這里僅作示例。

pkcs1 15 : RSA-SM3 : sm3WithRSAEncryption


3、  【執行命令自動更新】obj_mac.h和obj_mac.num

打開cmd,切換到目錄下源碼的cryptoobjects所在的目錄下,

執行命令:perl objects.pl objects.txt obj_mac.num obj_mac.h


obj_mac.h和obj_mac.num這兩個文件都會因為objects.txt的修改而更新。增加的內容如:


4、  【手動修改】objects.h

將obj_mac.h中新增的內容同步到objects.h中。(其實這一步不做也沒有影響,因為之后不用這個文件來生成obj_dat.h。objects.h的內容沒有obj_mac.h的內容全面,千萬不能用objects.h來obj_dat.h,一定要用obj_mac.h來生成才是正確的。切記,血的教訓!)

5、  【執行命令自動更新】obj_dat.h

執行命令:perl obj_dat.pl obj_mac.h obj_dat.h


將會自動更新obj_dat.h這個文件,新增的內容如下:


注意看圖上最后兩排

Line 4672: 921, /* OBJ_sm3 1 2 840 113549 2 12 */ Line 4843: 920, /* OBJ_sm3WithRSAEncryption 1 2 840 113549 1 1 15 */

最后帶的一串數字本來是算法的OID,因為上面第2步的objects.txt中是亂填的,所以這個不是真實的OID。僅作示例。

6、  【手動修改】obj_xref.txt

添加:

sm3WithRSAEncryption sm3 rsaEncryption

7、  【執行命令自動更新】obj_xref.h

執行命令:perl objxref.pl obj_xref.txt obj_xref.h

obj_xref.h更新后的添加的內容如:

五、make相關設置

1、  涉及到的文件util下面5個:

2、  【手動修改】mkfiles.pl

添加:

"crypto/sm3",



添加上包含sm3的算法源碼的目錄,這個目錄中包含sm3的Makefile文件。之后就會按照Makefile進行編譯。

3、  【手動修改】mkdef.pl

添加內容如圖:


加上新算法的頭文件等,可以在dll中導出算法函數。

4、  【執行命令自動更新】libeay.num

執行命令:perl util/mkdef.pl crypto update


Libeay.num更新后增加的內容如:


5、  【手動修改】mk1mf.pl

添加內容如:


6、  【手動修改】sp-diff.pl

添加內容如:


7、  涉及到的文件crypto下面2個:

8、  【手動修改】crypto-lib.com

添加內容如:

9、  【手動修改】install-crypto.com

添加內容如:

10、  涉及到的文件根目錄下面5個:

11、  【手動修改】

添加內容如圖:Makefile、Makefile.bak、Makefile.org、makevms.com、INSTALL.VMS

到這里,源碼需要添加和修改的就結束了,下面將介紹編譯和測試。

六、編譯

1、  在cmd下,首先設置VC環境,執行VC目錄下的vcvars32.BAT文件,如:

2、  cmd下進入openssl源碼所在的目錄,依次執行命令【編32位,如果64位可能缺ml64.exe】:

1)執行命令:perl Configure VC-WIN32 no-asm

2)  執行命令:msdo_ms

3)執行命令:nmake-f ms tdll.mak:這個是動態庫:如果編譯成功,最后的輸出都在out32dll目錄下: 包括可執行文件 、兩個dll和兩個lib文件【nmake -fms t.mak

這是靜態庫的編譯命令,輸出在out32目錄下】。編譯成功如圖:

4)  執行命令:nmake -fms tdll.mak test

5)執行命令:nmake -f ms tdll.mak install

七、測試

1、  API編程測試,在vs建工程,將openssl目錄下生成的out32dll文件夾下的libeay32.dll和libeay32.lib到工程。

2、  設置工程的附加庫和附加包含目錄:

右鍵工程->屬性-> C/C++ ->常規->附加包含目錄



右鍵工程->屬性-> 鏈接器 ->常規->附加庫目錄


3、  sm3test.c源碼如:

sm3test.c

#include <stdio.h> #include <openssl/evp.h> #include <openssl/sm3.h> #pragma comment(lib, "libeay32.lib") static size_t hash[8] = {0}; void out_hex(size_t *list1) { size_t i = 0; for (i = 0; i < 8; i++) { printf("%08x ", list1[i]); } printf(" "); } main(int argc, char *argv[]) { EVP_MD_CTX mdctx; const EVP_MD *md; char mess1[] = "abc"; char mess2[] = "abc"; unsigned char md_value[EVP_MAX_MD_SIZE]; int md_len, i; //使EVP_Digest系列函數支持所有有效的信息摘要算法 OpenSSL_add_all_digests(); argv[1] = "sm3"; if(!argv[1]) { printf("Usage: mdtest digestname "); exit(1); } //根據輸入的信息摘要函數的名字得到相應的EVP_MD算法結構 md = EVP_get_digestbyname(argv[1]); //md = EVP_sm3(); if(!md) { printf("Unknown message digest %s ", argv[1]); exit(1); } //初始化信息摘要結構mdctx,這在調用EVP_DigestInit_ex函數的時候是必須的。 EVP_MD_CTX_init(&mdctx); //使用md的算法結構設置mdctx結構,impl為NULL,即使用缺省實現的算法(openssl本身提供的信息摘要算法) EVP_DigestInit_ex(&mdctx, md, NULL); //開始真正進行信息摘要運算,可以多次調用該函數,處理更多的數據,這里只調用了兩次 EVP_DigestUpdate(&mdctx, mess1, strlen(mess1)); //EVP_DigestUpdate(&mdctx, mess2, strlen(mess2)); //完成信息摘要計算過程,將完成的摘要信息存儲在md_value里面,長度信息存儲在md_len里面 EVP_DigestFinal_ex(&mdctx, md_value, &md_len); //使用該函數釋放mdctx占用的資源,如果使用_ex系列函數,這是必須調用的。 EVP_MD_CTX_cleanup(&mdctx); printf("Digest is: "); for(i = 0; i < md_len; i++) printf("%02x", md_value[i]); printf(" "); //SM3("abc",3,hash); //out_hex(hash); system("pause"); } int main1(int argc, char* argv[]) { SM3_CTX *c = (SM3_CTX*)malloc(sizeof(SM3_CTX)); SM3_Init(c); //SM3_Final_dword(hash, c); SM3_Update(c, "abc", 3); SM3_Final(hash, c); out_hex(hash); //66c7f0f4 62eeedd9 d1f2d46b dc10e4e2 4167c487 5cf2f7a2 297da02b 8f4ba8e0 SM3_Init(c); SM3_Update(c, "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", 64); /*for (i = 0; i<16; i++){ SM3_Update(c, "abcd", 4); }*/ SM3_Final(hash,c); out_hex(hash); //debe9ff9 2275b8a1 38604889 c18e5a4d 6fdb70e5 387e5765 293dcba3 9c0c5732 //SM3("abc",3,hash); //out_hex(hash); system("pause"); return 0; }

4、  sm3test.c運行使用sm3算法對“abc”進行摘要后的結果如圖:


和國密標準的附錄示例一致:


八、總結

本例以摘要算法為例,具體介紹了一下通過直接添加源碼的方式怎樣在openssl里面添加新算法,而非engine方式。當然如果認為engine方式更方便,則請忽略本文。本文只是在描述怎么做,但是沒有講為什么。因為例如openssl本身的封裝機制是需要解讀源碼才能更好地理解上述文中為什么需要做那些步驟,因為這些步驟已經夠復雜了,所以解讀源碼將另起一篇文章。本文僅供依葫蘆畫瓢,要理解原理請自行查閱別的資料或者自己解讀源碼,或者等我的下一篇文章。

任何疑問或者指正請聯系我,謝謝!

小伙伴們加油!GOOD LUCK! 



生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 最近最新免费中文字幕高清 | 黄网址大全免费观看免费 | ww在线观视频免费观看w | 一区二区三区四区在线免费观看 | h视频在线观看视频观看 | 日韩中文字幕在线观看 | 日本欧美小视频 | 羞羞影院男女午夜爽爽影视 | 在线高清一级欧美精品 | 中国一级毛片国产高清 | 国产一起色一起爱 | 国产在线高清视频 | 成人9久久国产精品品 | xx性欧美 | 欧美喷 | 成人精品福利 | 波多野结衣手机视频一区 | 欧美曰韩一区二区三区 | 亚洲伦理一区二区 | 欧美va在线观看 | 曰本裸色私人影院噜噜噜影院 | 国产精品美乳免费看 | 高清在线播放 | 亚洲精品综合久久 | 亚洲天堂久久久 | 日本欧美一区二区三区视频麻豆 | 福利午夜影院 | 欧美黄色片在线观看 | 国产精品亚洲专一区二区三区 | 99久久国产综合精品女不卡 | 午夜dj影院在线观看免费视频中文 | 亚洲精品第1页 | 亚洲乱码在线观看 | 在线亚洲欧洲国产综合444 | 成人国产精品毛片 | 91极品国产| 亚洲图片小说网 | 国产欧美一区二区三区免费 | xx性欧美| 亚洲欧美日韩综合久久久久 | 免费91最新地址永久入口 |