openssl中添加新算法操作说明.docx

上传人:b****6 文档编号:5285481 上传时间:2022-12-14 格式:DOCX 页数:17 大小:2.07MB
下载 相关 举报
openssl中添加新算法操作说明.docx_第1页
第1页 / 共17页
openssl中添加新算法操作说明.docx_第2页
第2页 / 共17页
openssl中添加新算法操作说明.docx_第3页
第3页 / 共17页
openssl中添加新算法操作说明.docx_第4页
第4页 / 共17页
openssl中添加新算法操作说明.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

openssl中添加新算法操作说明.docx

《openssl中添加新算法操作说明.docx》由会员分享,可在线阅读,更多相关《openssl中添加新算法操作说明.docx(17页珍藏版)》请在冰豆网上搜索。

openssl中添加新算法操作说明.docx

openssl中添加新算法操作说明

1.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。

2.问题描述

openssl中虽然集成了很多经典算法,对称算法、非对称算法、摘要算法等等,但有时候我们需要用到自定义的算法,比如要实现一个自定义的摘要算法,需要借助openssl带的大数库来实现,同时又希望将自己实现的算法封装到openssl里面,以便统一调用或者方便项目改造和替换。

最具现实意义的案例就是国密SM2等的改造。

本例将用国密中的摘要算法SM3作为添加对象,在windows下面进行编译调试,仅描述添加步骤,所以本文的前提是已经完成了基于openssl大数库的SM3的c语言实现。

3.具体步骤

3.1.准备工作

1、 下载openssl源码,openssl目前最新的版本是openssl-1.0.1i。

下载地址:

2、 sm3的c语言实现。

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

4、 熟悉openssl的编译过程。

3.2.SM3代码改造

涉及到的文件7个:

1、 新建文件sm3.h

这是最重要的一个头文件,里面定义了算法可以导出的算法,也就是里面声明的每一个函数最后都会生成对应的libeay.num(将在第五章中具体讲),能够导出到dll中供外部调用。

几个主要的声明如下:

定义sm3的摘要长度:

#defineSM3_DIGEST_LENGTH32   /*sm3摘要长度为256位32字节,md5的摘要长度128位notsure*/

定义SM3_CTX,这个结构其实就是对应evp封装中EVP_MD_CTX的md_data:

typedefstructSM3state_st

{

unsignedlonglongtotal_length;

unsignedcharmessage_buffer[64];

size_tmessage_buffer_position;

size_tV_i[8];

size_tV_i_1[8];

size_tT_j[64];

}SM3_CTX;

声明函数,包括init、update、final,这几个函数会在封装的时候被内部调用,当然在dll中导出了也可以外部调用:

intSM3_Init(SM3_CTX*c);

intSM3_Update(SM3_CTX*c,constvoid*data,size_tlen);

intSM3_Final(unsignedchar*md,SM3_CTX*c);

unsignedchar*SM3(unsignedchar*d,size_tn,unsignedchar*md);

2、 新建文件sm3_locl.h

这个头文件中包含一些要用到的宏定义。

主要定义了本算法实现中需要用到的内部函数,不能被导出到dll中供外部调用。

宏定义:

#ifndefROTATE

#defineROTATE(a,n)(((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))

#endif

#defineEE(b,c,d)((b&c)|((~b)&d))

#defineFF(b,c,d)((((c)^(d))&(b))^(d))

#defineGG(b,c,d)(((b)&(c))|((b)&(d))|((c)&(d)))

#defineHH(b,c,d)((b)^(c)^(d))

#defineHH1(a)(a^(ROTATE(a,9))^(ROTATE(a,17)))

#defineHH2(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,unsignedchar*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文件。

里面描述在编译的时候以上的几个文件的角色、编译过程、依赖关系等。

3.3.EVP封装相关代码

涉及到的文件4个:

1、手动修改evp.h

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

#ifndefOPENSSL_NO_SM3

constEVP_MD*EVP_sm3(void);

#endif

说明:

EVP_sm3()函数将返回返回一个sm3的EVP_MD的结构,这个结构以及EVP_sm3()函数都在m_sm3.c中定义。

2、新建文件m_sm3.c

这是放在EVP目录中关于新算法的一个重要文件,定义 sm3 的EVP_MD结构,EVP_MD结构原型在evp.h中:

sm3的EVP_MD结构:

staticconstEVP_MDsm3_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),

};

3、手动修改c_alld.c

openssl的算法封装之后使用时需要加载算法,实现SM3的添加:

#ifndefOPENSSL_NO_SM3

EVP_add_digest(EVP_sm3());

#endif

4、手动修改Makefile

将编译时候的LIBSRC、LIBOBJ中加入SM3新算法,并且添加sm3各种头文件的依赖关系。

3.4.OID生成

1、 涉及到的文件7个:

2、 手动修改objects.txt

添加sm3的OID,特别说明:

此处仅作示例,sm3的实际OID是:

rsadsi212:

SM3:

sm3

添加sm3WithRSAEncryption,这个是对应PKCS1的,只是为了让sm3的EVP_MD结构有值填充,实际添加sm3的本意不用于RSA,这里仅作示例。

pkcs115:

RSA-SM3:

sm3WithRSAEncryption

3、 执行命令自动更新obj_mac.h和obj_mac.num

打开cmd,切换到目录下源码的\crypto\objects\所在的目录下,

执行命令:

perlobjects.plobjects.txtobj_mac.numobj_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

执行命令:

perlobj_dat.plobj_mac.hobj_dat.h

将会自动更新obj_dat.h这个文件,新增的内容如下:

注意看图上最后两排

Line4672:

921,/*OBJ_sm312840113549212*/

Line4843:

920,/*OBJ_sm3WithRSAEncryption128401135491115*/

最后带的一串数字本来是算法的OID,因为上面第2步的objects.txt中是乱填的,所以这个不是真实的OID。

仅作示例。

6、 手动修改 obj_xref.txt

添加:

sm3WithRSAEncryptionsm3rsaEncryption

7、 执行命令自动更新 obj_xref.h

执行命令:

perlobjxref.plobj_xref.txtobj_xref.h

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

3.5.make相关设置

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

2、 手动修改mkfiles.pl

添加:

"crypto/sm3",

添加上包含sm3的算法源码的目录,这个目录中包含sm3的Makefile文件。

之后就会按照Makefile进行编译。

3、 手动修改mkdef.pl

添加内容如图:

加上新算法的头文件等,可以在dll中导出算法函数。

4、 执行命令自动更新libeay.num

执行命令:

perlutil/mkdef.plcryptoupdate

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

5、 手动修改mk1mf.pl

添加内容如:

6、 手动修改sp-diff.pl

添加内容如:

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

8、 手动修改crypto-

添加内容如:

9、 手动修改install-

添加内容如:

10、 涉及到的文件根目录\下面5个:

11、 手动修改

添加内容如图:

Makefile、Makefile.bak、Makefile.org、、INSTALL.VMS

到这里,源码需要添加和修改的就结束了,下面将介绍编译和测试。

3.6.编译

1、 在cmd下,首先设置VC环境,执行VC目录下的vcvars32.BAT文件,如:

2、 cmd下进入openssl源码所在的目录,依次执行命令【编32位,如果64位可能缺ml64.exe】:

1)执行命令:

perlConfigureVC-WIN32no-asm

2) 执行命令:

ms\do_ms

3)执行命令:

nmake-fms\ntdll.mak:

这个是动态库:

如果编译成功,最后的输出都在out32dll目录下:

包括可执行文件、两个dll和两个lib文件【nmake-fms\nt.mak

这是静态库的编译命令,输出在out32目录下】。

编译成功如图:

4) 执行命令:

nmake-fms\ntdll.maktest

5)执行命令:

nmake-fms\ntdll.makinstall

七、测试

1、 API编程测试,在vs建工程,将openssl目录下生成的out32dll文件夹下的libeay32.dll和libeay32.lib到工程。

2、 设置工程的附加库和附加包含目录:

右键工程->属性->C/C++->常规->附加包含目录

右键工程->属性->链接器->常规->附加库目录

3、 sm3test.c源码如:

sm3test.c

#include

#include

#include

#pragmacomment(lib,"libeay32.lib")

staticsize_thash[8]={0};

voidout_hex(size_t*list1)

{

size_ti=0;

for(i=0;i<8;i++)

{

printf("%08x",list1[i]);

}

printf("\r\n");

}

main(intargc,char*argv[])

{

EVP_MD_CTXmdctx;

constEVP_MD*md;

charmess1[]="abc";

charmess2[]="abc";

unsignedcharmd_value[EVP_MAX_MD_SIZE];

intmd_len,i;

//使EVP_Digest系列函数支持所有有效的信息摘要算法

OpenSSL_add_all_digests();

argv[1]="sm3";

if(!

argv[1]){

printf("Usage:

mdtestdigestname\n");

exit

(1);

}

//根据输入的信息摘要函数的名字得到相应的EVP_MD算法结构

md=EVP_get_digestbyname(argv[1]);

//md=EVP_sm3();

if(!

md){

printf("Unknownmessagedigest%s\n",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("Digestis:

");

for(i=0;i

printf("\n");

//SM3("abc",3,hash);

//out_hex(hash);

system("pause");

}

 

intmain1(intargc,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);

//66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0

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);

//debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732

//SM3("abc",3,hash);

//out_hex(hash);

system("pause");

return0;

}

4、 sm3test.c运行使用sm3算法对“abc”进行摘要后的结果如图:

和国密标准的附录示例一致:

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 院校资料

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1