ImageVerifierCode 换一换
格式:DOCX , 页数:34 ,大小:39.28KB ,
资源ID:4289935      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/4289935.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Openssl之EVP.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Openssl之EVP.docx

1、Openssl之EVPOpenssl之EVP系列作者: LaoKa200804261.算法封装EVP系列的函数定义包含在evp.h里面,这是一系列封装了openssl加密库里面所有算法的函数。通过这样的统一的封装,使得只需要在初始化参数的时候做很少的改变,就可以使用相同的代码但采用不同的加密算法进行数据的加密和解密。EVP系列函数主要封装了三大类型的算法,要支持全部这些算法,请调用OpenSSL_add_all_algorithms函数,下面分别就其结构作一个简单的介绍。1.1公开密钥算法函数名称:EVP_Seal*.*,EVP_Open*.*功能描述:该系列函数封装提供了公开密钥算法的加密和

2、解密功能,实现了电子信封的功能。相关文件:p_seal.c,p_open.c1.2数字签名算法函数名称:EVP_Sign*.*,EVP_Verify*.*功能描述:该系列函数封装提供了数字签名算法和功能。相关文件:p_sign.c,p_verify.c1.3对称加密算法函数名称:EVP_Encrypt*.*功能描述:该系列函数封装提供了对称加密算法的功能。相关文件:evp_enc.c,p_enc.c,p_dec.c,e_*.c1.4信息摘要算法函数名称:EVP_Digest*.*功能描述:该系列函数封装实现了多种信息摘要算法。相关文件:digest.c,m_*.c1.5信息编码算法函数名称:E

3、VP_Encode*.*功能描述:该系列函数封装实现了ASCII码与二进制码之间的转换函数和功能。相关文件:encode.c注意:自从出现engin版本以后,所有对称加密算法和摘要算法可以用ENGINE模块实现的算法代替。如果ENGINE模块实现的对称加密和信息摘要函数被注册为缺省的实现算法,那么当使用各种EVP函数时,软件编译的时候会自动将该实现模块连接进去。2.对称加密算法概述对称加密算法封装的函数系列名字是以EVP_Encrypt*.*开头的,其实,这些函数只是简单调用了EVP_Cipher*.*系列的同名函数,换一个名字可能是为了更好的区别和理解。除了实现了对称加密算法外,EVP_En

4、crypt*.*系列还对块加密算法提供了缓冲功能。以后我们可能会更多使用EVP_Cipher的术语,因为它是真正的实现结构。EVP_Cipher*.*得以实现的一个基本结构是下面定义的一个算法结构,它定义了EVP_Cipher系列函数应该采用什么算法进行数据处理,其定义如下(evp.h):typedef struct evp_cipher_stint nid;int block_size;int key_len;int iv_len;unsigned long flags;int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key, co

5、nst unsigned char *iv, int enc);int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl);int (*cleanup)(EVP_CIPHER_CTX *);int ctx_size;int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *);int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *);int (

6、*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Miscellaneous operations */void *app_data;EVP_CIPHER;下面对这个结构的部分成员的含义作一些解释:1. nid是算法类型的nid识别号,openssl里面每个对象都有一个内部唯一的识别ID2. block_size是每次加密的数据块的长度,以字节为单位3. key_len各种不同算法缺省的密钥长度4. iv_len初始化向量的长度5. init算法结构初始化函数,可以设置为加密模式还是解密模式6. do_cipher进行数据加密

7、或解密的函数7. cleanup释放EVP_CIPHER_CTX结构里面的数据和设置。8. ctx_size设定ctx-cipher_data数据的长度9. set_asn1_parameters在EVP_CIPHER_CTX结构中通过参数设置一个ASN1_TYPE10. get_asn1_parameters从一个ASN1_TYPE中取得参数11. ctrl其它各种操作函数12. app_data应用数据通过定义这样一个指向这个结构的指针,你就可以在连接程序的时候只连接自己使用的算法;而如果你是通过一个整数来指明应该使用什么算法的话,会导致所有算法的代码都被连接到代码中。通过这样一个结构,还

8、可以自己增加新的算法。在这个基础上,每个EVP_Cipher*.*函数都维护着一个指向一个EVP_CIPHER_CTX结构的指针。typedef struct evp_cipher_ctx_stconst EVP_CIPHER *cipher;ENGINE *engine;int encrypt;int buf_len;unsigned char oivEVP_MAX_IV_LENGTH;unsigned char ivEVP_MAX_IV_LENGTH;unsigned char bufEVP_MAX_BLOCK_LENGTH;int num;void *app_data;int key_l

9、en;unsigned long flags;void *cipher_data;int final_used;int block_mask;unsigned char finalEVP_MAX_BLOCK_LENGTH; EVP_CIPHER_CTX;下面对这个结构部分成员做简单的解释:1. cipher是该结构相关的一个EVP_CIPHER算法结构2. engine如果加密算法是ENGINE提供的,那么该成员保存了相关的函数接口3. encrypt加密或解密的标志4. buf_len该结构缓冲区里面当前的数据长度5. oiv初始的初始化向量6. iv工作时候使用的初始化向量7. buf保存

10、下来的部分需要数据8. num在cfb/ofb模式的时候指定块长度9. app_data应用程序要处理数据10. key_len密钥长度,算法不一样长度也不一样11. cipher_data加密后的数据上述两个结构是EVP_Cipher(EVP_Encrypt)系列的两个基本结构,它们的其它一些列函数都是以这两个结构为基础实现了。文件evpevp_enc.c是最高层的封装实现,各种加密的算法的封装在p_enc.c里面实现,解密算法的封装在p_dec.c里面实现,而各个e_*.c文件则是真正实现了各种算法的加解密功能,当然它们其实也是一些封装函数,真正的算法实现在各个算法同名目录里面的文件实现。

11、3.EVP_Encrypt支持的对称加密算法列表openssl对称加密算法的格式都以函数形式提供,其实该函数返回一个该算法的结构体,其形式一般如下:EVP_CIPHER* EVP_*(void)在openssl中,所有提供的对称加密算法长度都是固定的,有特别说明的除外。下面对这些算法进行分类的介绍,首先介绍一下算法中使用的通用标志的含义。通用标志:ecb电子密码本(Electronic Code Book)加密方式cbc加密块链接(Cipher Block Chaining)加密方式cfb64位加密反馈(Cipher Feedback)加密方式ofb64位输出反馈(Output Feedbac

12、k)加密方式ede该加密算法采用了加密、解密、加密的方式,第一个密钥和最后一个密钥是相同的ede3该加密算法采用了加密、解密、加密的方式,但是三个密钥都不相同3.1 NULL算法函数:EVP_enc_null()说明:该算法不作任何事情,也就是没有进行加密处理3.2 DES算法函数:EVP_des_cbc(void), EVP_des_ecb(void), EVP_des_cfb(void), EVP_des_ofb(void)说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的DES算法3.3 使用两个密钥的3DES算法函数:EVP_des_ede_cbc(void), EVP_d

13、es_ede(), EVP_des_ede_ofb(void),EVP_des_ede_cfb(void)说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的3DES算法,算法的第一个密钥和最后一个密钥相同,事实上就只需要两个密钥3.4 使用三个密钥的3DES算法函数:EVP_des_ede3_cbc(void), EVP_des_ede3(), EVP_des_ede3_ofb(void), EVP_des_ede3_cfb(void)说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的3DES算法,算法的三个密钥都不相同3.5 DESX算法函数:EVP_desx_cbc

14、(void)说明:CBC方式DESX算法3.6 RC4算法函数:EVP_rc4(void)说明:RC4流加密算法。该算法的密钥长度可以改变,缺省是128位。3.7 40位RC4算法函数:EVP_rc4_40(void)说明:密钥长度40位的RC4流加密算法。该函数可以使用EVP_rc4和EVP_CIPHER_CTX_set_key_length函数代替。3.8 IDEA算法函数:EVP_idea_cbc(),EVP_idea_ecb(void), EVP_idea_cfb(void), EVP_idea_ofb(void)说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的IDEA算

15、法。3.9 RC2算法函数:EVP_rc2_cbc(void), EVP_rc2_ecb(void), EVP_rc2_cfb(void), EVP_rc2_ofb(void)说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的RC2算法,该算法的密钥长度是可变的,可以通过设置有效密钥长度或有效密钥位来设置参数来改变。缺省的是128位。3.10 定长的两种RC2算法函数:EVP_rc2_40_cbc(void), EVP_rc2_64_cbc(void)说明:分别是40位和64位CBC模式的RC2算法。3.11 Blowfish算法函数:EVP_bf_cbc(void), EVP_b

16、f_ecb(void), EVP_bf_cfb(void), EVP_bf_ofb(void)说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的Blowfish算法,该算法的密钥长度是可变的3.12 CAST算法函数:EVP_cast5_cbc(void), EVP_cast5_ecb(void), EVP_cast5_cfb(void), EVP_cast5_ofb(void)说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的CAST算法,该算法的密钥长度是可变的3.13 RC5算法函数:EVP_rc5_32_12_16_cbc(void), EVP_rc5_32_1

17、2_16_ecb(void), EVP_rc5_32_12_16_cfb(void), EVP_rc5_32_12_16_ofb(void)说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的RC5算法,该算法的密钥长度可以根据参数“number of rounds”(算法中一个数据块被加密的次数)来设置,缺省的是128位密钥,加密次数为12次。目前来说,由于RC5算法本身实现代码的限制,加密次数只能设置为8、12或16。3.14 128位AES算法函数:EVP_aes_128_ecb(void),EVP_aes_128_cbc(void),PEVP_aes_128_cfb(void

18、),EVP_aes_128_ofb(void)说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的128位AES算法3.15 192位AES算法函数:EVP_aes_192_ecb(void),EVP_aes_192_cbc(void),PEVP_aes_192_cfb(void),EVP_aes_192_ofb(void)说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的192位AES算法3.16 256位AES算法函数:EVP_aes_256_ecb(void),EVP_aes_256_cbc(void),PEVP_aes_256_cfb(void),EVP_aes_

19、256_ofb(void)说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的256位AES算法4.EVP_Encrypt系列函数详解(一)EVP_Cipher系列包含了很多函数,我将他们大概分成两部分来介绍,一部分是基本函数系列,就是本文要介绍的,另一个部分是设置函数系列,将在后面的文章进行介绍。基本系列函数主要是进行基本的加密和解密操作的函数,他们的定义如下(opensslevp.h):int EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_C

20、IPHER *type, ENGINE *impl, unsigned char *key, unsigned char *iv);int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, unsigned char *in, int inl);int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CI

21、PHER *type, ENGINE *impl, unsigned char *key, unsigned char *iv);int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, unsigned char *in, int inl);int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIP

22、HER *type, ENGINE *impl, unsigned char *key, unsigned char *iv, int enc);int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, unsigned char *in, int inl);int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP

23、_CIPHER *type, unsigned char *key, unsigned char *iv);int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char *key, unsigned char *iv);int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *o

24、utl);int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char *key, unsigned char *iv, int enc);int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);其实在这里列出的函数虽然很多,但是大部分是功能重复的,有的是旧的版本支持的函数,新的版本中已经可以不再使用了。事实上,函数EVP

25、_EncryptInit, EVP_EncryptFinal, EVP_DecryptInit, EVP_CipherInit以及EVP_CipherFinal在新代码中不应该继续使用,他们保留下来只是为了兼容以前的代码。在新的代码中,应该使用EVP_EncryptInit_ex、EVP_EncryptFinal_ex、EVP_DecryptInit_ex、EVP_DecryptFinal_ex、EVP_CipherInit_ex以及EVP_CipherFinal_ex函数,因为它们可以在每次调用完算法后,不用重新释放和分配已有EVP_CIPHER_CTX结构的内存的情况下重用该结构,方便很多

26、。下面我们分别对这些函数进行介绍。4.1 EVP_CIPHER_CTX_init该函数初始化一个EVP_CIPHER_CTX结构体,只有初始化后该结构体才能在下面介绍的函数中使用。操作成功返回1,否则返回0。4.2 EVP_EncryptInit_ex该函数采用ENGINE参数impl的算法来设置并初始化加密结构体。其中,参数ctx必须在调用本函数之前已经进行了初始化。参数type通常通过函数类型来提供参数,如EVP_des_cbc函数的形式,即我们上一章中介绍的对称加密算法的类型。如果参数impl为NULL,那么就会使用缺省的实现算法。参数key是用来加密的对称密钥,iv参数是初始化向量(如

27、果需要的话)。在算法中真正使用的密钥长度和初始化密钥长度是根据算法来决定的。在调用该函数进行初始化的时候,除了参数type之外,所有其它参数可以设置为NULL,留到以后调用其它函数的时候再提供,这时候参数type就设置为NULL就可以了。在缺省的加密参数不合适的时候,可以这样处理。操作成功返回1,否则返回0。4.3 EVP_EncryptUpdate该函数执行对数据的加密。该函数加密从参数in输入的长度为inl的数据,并将加密好的数据写入到参数out里面去。可以通过反复调用该函数来处理一个连续的数据块。写入到out的数据数量是由已经加密的数据的对齐关系决定的,理论上来说,从0到(inl+cip

28、her_block_size-1)的任何一个数字都有可能(单位是字节),所以输出的参数out要有足够的空间存储数据。写入到out中的实际数据长度保存在outl参数中。操作成功返回1,否则返回0。4.4 EVP_EncryptFinal_ex该函数处理最后(Final)的一段数据。函数在padding功能打开的时候(缺省)才有效,这时候,它将剩余的最后的所有数据进行加密处理。该算法使用标志的块padding方式(AKA PKCS padding)。加密后的数据写入到参数out里面,参数out的长度至少应该能够一个加密块。写入的数据长度信息输入到outl参数里面。该函数调用后,表示所有数据都加密完

29、了,不应该再调用EVP_EncryptUpdate函数。如果没有设置padding功能,那么本函数不会加密任何数据,如果还有剩余的数据,那么就会返回错误信息,也就是说,这时候数据总长度不是块长度的整数倍。操作成功返回1,否则返回0。PKCS padding标准是这样定义的,在被加密的数据后面加上n个值为n的字节,使得加密后的数据长度为加密块长度的整数倍。无论在什么情况下,都是要加上padding的,也就是说,如果被加密的数据已经是块长度的整数倍,那么这时候n就应该等于块长度。比如,如果块长度是9,要加密的数据长度是11,那么5个值为5的字节就应该增加在数据的后面。4.5 EVP_Decrypt

30、Init_ex, EVP_DecryptUpdate和EVP_DecryptFinal_ex这三个函数是上面三个函数相应的解密函数。这些函数的参数要求基本上都跟上面相应的加密函数相同。如果padding功能打开了,EVP_DecryptFinal会检测最后一段数据的格式,如果格式不正确,该函数会返回错误代码。此外,如果打开了padding功能,EVP_DecryptUpdate函数的参数out的长度应该至少为(inl+cipher_block_size)字节;但是,如果加密块的长度为1,则其长度为inl字节就足够了。三个函数都是操作成功返回1,否则返回0。需要注意的是,虽然在padding功能

31、开启的情况下,解密操作提供了错误检测功能,但是该功能并不能检测输入的数据或密钥是否正确,所以即便一个随机的数据块也可能无错的完成该函数的调用。如果padding功能关闭了,那么当解密数据长度是块长度的整数倍时,操作总是返回成功的结果。4.6 EVP_CipherInit_ex, EVP_CipherUpdate和EVP_CipherFinal_ex事实上,上面介绍的函数都是调用这三个函数实现的,它们是更底层的函数。完成了数据的加密和解密功能。他们根据参数enc决定执行加密还是解密操作,如果enc为1,则加密;如果enc为0,则解密;如果enc是1,则不改变数据。三个函数都是操作成功返回1,否则返回0。4.7 EVP_CIPHER_CTX_cleanup该函数清除一个EVP_CIPHER_CTX结构中的所有信息并释放该结构占用的所有内存。在使用上述的函数完成一个加密算法过程后应该调用该函数,这样可以避免一些敏感信息遗留在内存造成安全隐犯。操作成功返回1,否则返回0。4.8 EVP_EncryptInit, EVP_DecryptInit和EVP_CipherInit这三个函数的功能分别跟函数EVP_EncryptInit_ex,

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

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