文档库 最新最全的文档下载
当前位置:文档库 › openssl的EVP函数详解

openssl的EVP函数详解

openssl的EVP函数详解
openssl的EVP函数详解

openssl之EVP系列之1---算法封装

---根据openssl doc\crypto\EVP.pod翻译和自己的理解写成

(作者:DragonKing, Mail: wzhah@https://www.wendangku.net/doc/1f9363347.html, ,发布于:https://www.wendangku.net/doc/1f9363347.html,之

openssl专业论坛,版本:openssl-0.9.7)

EVP系列的函数定义包含在"evp.h"里面,这是一系列封装了openssl加密库里面所有

算法的函数。通过这样的统一的封装,使得只需要在初始化参数的时候做很少的改变,

就可以使用相同的代码但采用不同的加密算法进行数据的加密和解密。

EVP系列函数主要封装了三大类型的算法,要支持全部这些算法,请调用OpenSSL_a dd_all_algorithms函数,下面分别就其结构作一个简单的介绍。

【公开密钥算法】

函数名称:EVP_Seal*...*,EVP_Open*...*

功能描述:该系列函数封装提供了公开密钥算法的加密和解密功能,实现了电子信

封的功能。

相关文件:p_seal.c,p_open.c

【数字签名算法】

函数名称:EVP_Sign*...*,EVP_Verify*...*

功能描述:该系列函数封装提供了数字签名算法和功能。

相关文件:p_sign.c,p_verify.c

【对称加密算法】

函数名称:EVP_Encrypt*...*

功能描述:该系列函数封装提供了对称加密算法的功能。

相关文件:evp_enc.c,p_enc.c,p_dec.c,e_*.c

【信息摘要算法】

函数名称:EVP_Digest*...*

功能描述:该系列函数封装实现了多种信息摘要算法。

相关文件:digest.c,m_*.c

【信息编码算法】

函数名称:EVP_Encode*...*

功能描述:该系列函数封装实现了ASCII码与二进制码之间的转换函数和功能。

相关文件:encode.c

注意:

自从出现engin版本以后,所有对称加密算法和摘要算法可以用ENGINE模块实现的算法代替。如果ENGINE模块实现的对称加密和信息摘要函数被注册为缺省的实现算法,那么当使用各种EVP函数时,软件编译的时候会自动将该实现模块连接进去。

openssl之EVP系列之2---对称加密算法概述

---根据openssl doc\crypto\EVP_EncryptInit.pod和doc\ssleay.txt cipher.doc

部分翻译和自己的理解写成

(作者:DragonKing, Mail: wzhah@https://www.wendangku.net/doc/1f9363347.html, ,发布于:https://www.wendangku.net/doc/1f9363347.html,之

openssl专业论坛,版本:openssl-0.9.7)

对称加密算法封装的函数系列名字是以EVP_Encrypt*...*开头的,其实,这些函数

只是简单调用了EVP_Cipher*...*系列的同名函数,换一个名字可能是为了更好的区别和

理解。除了实现了对称加密算法外,EVP_Encrypt*...*系列还对块加密算法提供了缓冲

功能。以后我们可能会更多使用EVP_Cipher的术语,因为它是真正的实现结构。

EVP_Cipher*...*得以实现的一个基本结构是下面定义的一个算法结构,它定义了E

VP_Cipher系列函数应该采用什么算法进行数据处理,其定义如下(evp.h):

typedef struct evp_cipher_st

{

int nid;

int block_size;

int key_len;

int iv_len;

unsigned long flags;

int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsign

ed char *iv, int enc);

int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigne

d 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 (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Miscell

aneous operations */

void *app_data;

}EVP_CIPHER;

下面对这个结构的部分成员的含义作一些解释:

nid——是算法类型的nid识别号,openssl里面每个对象都有一个内部唯一的识别I

D

block_size——是每次加密的数据块的长度,以字节为单位

key_len——各种不同算法缺省的密钥长度

iv_len——初始化向量的长度

init——算法结构初始化函数,可以设置为加密模式还是解密模式

do_cipher——进行数据加密或解密的函数

cleanup——释放EVP_CIPHER_CTX结构里面的数据和设置。

ctx_size——设定ctx->cipher_data数据的长度

set_asn1_parameters——在EVP_CIPHER_CTX结构中通过参数设置一个ASN1_TYPE get_asn1_parameters——从一个ASN1_TYPE中取得参数

ctrl——其它各种操作函数

app_data——应用数据

通过定义这样一个指向这个结构的指针,你就可以在连接程序的时候只连接自己使

用的算法;而如果你是通过一个整数来指明应该使用什么算法的话,会导致所有算法的代码都被连接到代码中。通过这样一个结构,还可以自己增加新的算法。

在这个基础上,每个EVP_Cipher*...*函数都维护着一个指向一个EVP_CIPHER_CTX结构的指针。

typedef struct evp_cipher_ctx_st

{

const EVP_CIPHER *cipher;

ENGINE *engine;

int encrypt;

int buf_len;

unsigned char oiv[EVP_MAX_IV_LENGTH];

unsigned char iv[EVP_MAX_IV_LENGTH];

unsigned char buf[EVP_MAX_BLOCK_LENGTH];

int num;

void *app_data;

int key_len;

unsigned long flags;

void *cipher_data;

int final_used;

int block_mask;

unsigned char final[EVP_MAX_BLOCK_LENGTH];

} EVP_CIPHER_CTX;

下面对这个结构部分成员做简单的解释:

cipher——是该结构相关的一个EVP_CIPHER算法结构

engine——如果加密算法是ENGINE提供的,那么该成员保存了相关的函数接口

encrypt——加密或解密的标志

buf_len——该结构缓冲区里面当前的数据长度

oiv——初始的初始化向量

iv——工作时候使用的初始化向量

buf——保存下来的部分需要数据

num——在cfb/ofb模式的时候指定块长度

app_data——应用程序要处理数据

key_len——密钥长度,算法不一样长度也不一样

cipher_data——加密后的数据

上述两个结构是EVP_Cipher(EVP_Encrypt)系列的两个基本结构,它们的其它一些列函数都是以这两个结构为基础实现了。文件evp\evp_enc.c是最高层的封装实现,各种加密的算法的封装在p_enc.c里面实现,解密算法的封装在p_dec.c里面实现,而各个e_*. c文件则是真正实现了各种算法的加解密功能,当然它们其实也是一些封装函数,真正的算法实现在各个算法同名目录里面的文件实现。

openssl之EVP系列之3---EVP_Encrypt支持的对称加密算法列表

---根据openssl doc\crypto\EVP_EncryptInit.pod和doc\ssleay.txt cipher.doc

部分翻译和自己的理解写成

(作者:DragonKing, Mail: wzhah@https://www.wendangku.net/doc/1f9363347.html, ,发布于:https://www.wendangku.net/doc/1f9363347.html,之

openssl专业论坛,版本:openssl-0.9.7)

openssl对称加密算法的格式都以函数形式提供,其实该函数返回一个该算法的结构体,其形式一般如下:

EVP_CIPHER* EVP_*(void)

在openssl中,所有提供的对称加密算法长度都是固定的,有特别说明的除外。下面

对这些算法进行分类的介绍,首先介绍一下算法中使用的通用标志的含义。

【通用标志】

ecb——电子密码本(Electronic Code Book)加密方式

cbc——加密块链接(Cipher Block Chaining)加密方式

cfb——64位加密反馈(Cipher Feedback)加密方式

ofb——64位输出反馈(Output Feedback)加密方式

ede——该加密算法采用了加密、解密、加密的方式,第一个密钥和最后一个密钥是

相同的

ede3——该加密算法采用了加密、解密、加密的方式,但是三个密钥都不相同

【NULL算法】

函数:EVP_enc_null()

说明:该算法不作任何事情,也就是没有进行加密处理

【DES算法】

函数:EVP_des_cbc(void), EVP_des_ecb(void), EVP_des_cfb(void), EVP_des_o

fb(void)

说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的DES算法

【使用两个密钥的3DES算法】

函数:EVP_des_ede_cbc(void), EVP_des_ede(), EVP_des_ede_ofb(void),EVP_de

s_ede_cfb(void)

说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的3DES算法,算法的第一个

密钥和最后一个密钥相同,事实上就只需要两个密钥

【使用三个密钥的3DES算法】

函数:EVP_des_ede3_cbc(void), EVP_des_ede3(), EVP_des_ede3_ofb(void), EV

P_des_ede3_cfb(void)

说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的3DES算法,算法的三个密

钥都不相同

【DESX算法】

函数:EVP_desx_cbc(void)

说明:CBC方式DESX算法

【RC4算法】

函数:EVP_rc4(void)

说明:RC4流加密算法。该算法的密钥长度可以改变,缺省是128位。

【40位RC4算法】

函数:EVP_rc4_40(void)

说明:密钥长度40位的RC4流加密算法。该函数可以使用EVP_rc4和EVP_CIPHER_CTX _set_key_length函数代替。

【IDEA算法】

函数:EVP_idea_cbc(),EVP_idea_ecb(void), EVP_idea_cfb(void), EVP_idea_o

fb(void)

说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的IDEA算法。

【RC2算法】

函数:EVP_rc2_cbc(void), EVP_rc2_ecb(void), EVP_rc2_cfb(void), EVP_rc2_o

fb(void)

说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的RC2算法,该算法的密钥长

度是可变的,可以通过设置有效密钥长度或有效密钥位来设置参数来改变。缺省的是12

8位。

【定长的两种RC2算法】

函数:EVP_rc2_40_cbc(void), EVP_rc2_64_cbc(void)

说明:分别是40位和64位CBC模式的RC2算法。

【Blowfish算法】

函数:EVP_bf_cbc(void), EVP_bf_ecb(void), EVP_bf_cfb(void), EVP_bf_ofb(v

oid)

说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的Blowfish算法,该算法的

密钥长度是可变的

【CAST算法】

函数:EVP_cast5_cbc(void), EVP_cast5_ecb(void), EVP_cast5_cfb(void), EVP

_cast5_ofb(void)

说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的CAST算法,该算法的密钥

长度是可变的

【RC5算法】

函数:EVP_rc5_32_12_16_cbc(void), EVP_rc5_32_12_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。

【128位AES算法】

函数:EVP_aes_128_ecb(void),EVP_aes_128_cbc(void),PEVP_aes_128_cfb(voi

d),EVP_aes_128_ofb(void)

说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的128位AES算法【192位AES算法】

函数:EVP_aes_192_ecb(void),EVP_aes_192_cbc(void),PEVP_aes_192_cfb(voi

d),EVP_aes_192_ofb(void)

说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的192位AES算法【256位AES算法】

函数:EVP_aes_256_ecb(void),EVP_aes_256_cbc(void),PEVP_aes_256_cfb(voi

d),EVP_aes_256_ofb(void)

说明:分别是CBC方式、ECB方式、CFB方式以及OFB方式的256位AES算法

上述的算法是0.9.7版本支持的所有对称加密算法,关于算法的详细情况,请参看该

算法的资料了或本系列后续的文章。

openssl之EVP系列之4---EVP_Encrypt系列函数详解(一)

---根据openssl doc\crypto\EVP_EncryptInit.pod和doc\ssleay.txt cipher.doc

部分翻译和自己的理解写成

(作者:DragonKing, Mail: wzhah@https://www.wendangku.net/doc/1f9363347.html, ,发布于:https://www.wendangku.net/doc/1f9363347.html,之openssl专业论坛,版本:openssl-0.9.7)

EVP_Cipher系列包含了很多函数,我将他们大概分成两部分来介绍,一部分是基本函数系列,就是本文要介绍的,另一个部分是设置函数系列,将在后面的文章进行介绍。基本系列函数主要是进行基本的加密和解密操作的函数,他们的定义如下(openssl\ evp.h):

int EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);

int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *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_CIPHER *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_CIPHER *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_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 *outl);

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_EncryptInit, EVP_Encry

ptFinal, EVP_DecryptInit, EVP_CipherInit以及EVP_CipherFinal在新代码中不应该继

续使用,他们保留下来只是为了兼容以前的代码。在新的代码中,应该使用EVP_Encryp tInit_ex、EVP_EncryptFinal_ex、EVP_DecryptInit_ex、EVP_DecryptFinal_ex、EVP_ CipherInit_ex以及EVP_CipherFinal_ex函数,因为它们可以在每次调用完算法后,不用

重新释放和分配已有EVP_CIPHER_CTX结构的内存的情况下重用该结构,方便很多。下面我们分别对这些函数进行介绍。

【EVP_CIPHER_CTX_init】

该函数初始化一个EVP_CIPHER_CTX结构体,只有初始化后该结构体才能在下面介绍的函数中使用。操作成功返回1,否则返回0。

【EVP_EncryptInit_ex】

该函数采用ENGINE参数impl的算法来设置并初始化加密结构体。其中,参数ctx必须在调用本函数之前已经进行了初始化。参数type通常通过函数类型来提供参数,如EVP_ des_cbc函数的形式,即我们上一章中介绍的对称加密算法的类型。如果参数impl为NUL L,那么就会使用缺省的实现算法。参数key是用来加密的对称密钥,iv参数是初始化向

量(如果需要的话)。在算法中真正使用的密钥长度和初始化密钥长度是根据算法来决

定的。在调用该函数进行初始化的时候,除了参数type之外,所有其它参数可以设置为NULL,留到以后调用其它函数的时候再提供,这时候参数type就设置为NULL就可以了。在缺省的加密参数不合适的时候,可以这样处理。操作成功返回1,否则返回0。

【EVP_EncryptUpdate】

该函数执行对数据的加密。该函数加密从参数in输入的长度为inl的数据,并将加密

好的数据写入到参数out里面去。可以通过反复调用该函数来处理一个连续的数据块。写

入到out的数据数量是由已经加密的数据的对齐关系决定的,理论上来说,从0到(inl+c ipher_block_size-1)的任何一个数字都有可能(单位是字节),所以输出的参数out要

有足够的空间存储数据。写入到out中的实际数据长度保存在outl参数中。操作成功返回1,否则返回0。

【EVP_EncryptFinal_ex】

该函数处理最后(Final)的一段数据。在函数在padding功能打开的时候(缺省)

才有效,这时候,它将剩余的最后的所有数据进行加密处理。该算法使用标志的块padd ing方式(AKA PKCS padding)。加密后的数据写入到参数out里面,参数out的长度至少

应该能够一个加密块。写入的数据长度信息输入到outl参数里面。该函数调用后,表示

所有数据都加密完了,不应该再调用EVP_EncryptUpdate函数。如果没有设置padding功能,那么本函数不会加密任何数据,如果还有剩余的数据,那么就会返回错误信息,也

就是说,这时候数据总长度不是块长度的整数倍。操作成功返回1,否则返回0。

PKCS padding标准是这样定义的,在被加密的数据后面加上n个值为n的字节,使得

加密后的数据长度为加密块长度的整数倍。无论在什么情况下,都是要加上padding的,

也就是说,如果被加密的数据已经是块长度的整数倍,那么这时候n就应该等于块长度。比如,如果块长度是9,要加密的数据长度是11,那么5个值为5的字节就应该增加在数据的后面。

【EVP_DecryptInit_ex, EVP_DecryptUpdate和EVP_DecryptFinal_ex】

这三个函数是上面三个函数相应的解密函数。这些函数的参数要求基本上都跟上面

相应的加密函数相同。如果padding功能打开了,EVP_DecryptFinal会检测最后一段数据

的格式,如果格式不正确,该函数会返回错误代码。此外,如果打开了padding功能,E VP_DecryptUpdate函数的参数out的长度应该至少为(inl+cipher_block_size)字节;

但是,如果加密块的长度为1,则其长度为inl字节就足够了。三个函数都是操作成功返

回1,否则返回0。

需要注意的是,虽然在padding功能开启的情况下,解密操作提供了错误检测功能,

但是该功能并不能检测输入的数据或密钥是否正确,所以即便一个随机的数据块也可能

无错的完成该函数的调用。如果padding功能关闭了,那么当解密数据长度是块长度的整数倍时,操作总是返回成功的结果。

【EVP_CipherInit_ex, EVP_CipherUpdate和EVP_CipherFinal_ex】

事实上,上面介绍的函数都是调用这三个函数实现的,它们是更底层的函数。完成

了数据的加密和解密功能。他们根据参数enc决定执行加密还是解密操作,如果enc为1,则加密;如果enc为0,则解密;如果enc是-1,则不改变数据。三个函数都是操作成功返回1,否则返回0。

【EVP_CIPHER_CTX_cleanup】

该函数清除一个EVP_CIPHER_CTX结构中的所有信息并释放该结构占用的所有内存。在使用上述的函数完成一个加密算法过程后应该调用该函数,这样可以避免一些敏感信

息遗留在内存造成安全隐犯。操作成功返回1,否则返回0。

【EVP_EncryptInit, EVP_DecryptInit和EVP_CipherInit】

这三个函数的功能分别跟函数EVP_EncryptInit_ex, EVP_DecryptInit_ex和EVP_Ci pherInit_ex功能相同,只是他们的ctx参数不需要进行初始化,并且使用缺省的算法库

。三个函数都是操作成功返回1,否则返回0。

【EVP_EncryptFinal, EVP_DecryptFinal和EVP_CipherFinal】

这三个函数分别跟函数EVP_EncryptFinal_ex, EVP_DecryptFinal_ex以及EVP_Ciph erFinal_ex函数功能相同,不过,他们的参数ctx会在调用后自动释放。三个函数都是操

作成功返回1,否则返回0。

openssl之EVP系列之5---EVP_Encrypt系列函数详解(二)

---根据openssl doc\crypto\EVP_EncryptInit.pod和doc\ssleay.txt cipher.doc

部分翻译和自己的理解写成

(作者:DragonKing, Mail: wzhah@https://www.wendangku.net/doc/1f9363347.html, ,发布于:https://www.wendangku.net/doc/1f9363347.html,之

openssl专业论坛,版本:openssl-0.9.7)

前面的文章我们介绍了EVP_ENcrypt系列函数的基本部分,本文将介绍他们的一些扩

充部分,即一些参数设置和其它辅助的函数,其定义如下(openssl\evp.h):

int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *x, int padding);

int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);

const EVP_CIPHER *EVP_get_cipherbyname(const char *name);

#define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a))

#define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a))

int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);

#define EVP_CIPHER_nid(e) ((e)->nid)

#define EVP_CIPHER_block_size(e) ((e)->block_size)

#define EVP_CIPHER_key_length(e) ((e)->key_len)

#define EVP_CIPHER_iv_length(e) ((e)->iv_len)

#define EVP_CIPHER_flags(e) ((e)->flags)

#define EVP_CIPHER_mode(e) ((e)->flags) & EVP_CIPH_MODE)

int EVP_CIPHER_type(const EVP_CIPHER *ctx);

#define EVP_CIPHER_CTX_cipher(e) ((e)->cipher)

#define EVP_CIPHER_CTX_nid(e) ((e)->cipher->nid)

#define EVP_CIPHER_CTX_block_size(e) ((e)->cipher->block_size)

#define EVP_CIPHER_CTX_key_length(e) ((e)->key_len)

#define EVP_CIPHER_CTX_iv_length(e) ((e)->cipher->iv_len)

#define EVP_CIPHER_CTX_get_app_data(e) ((e)->app_data)

#define EVP_CIPHER_CTX_set_app_data(e,d) ((e)->app_data=(char *)(d))

#define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)

)

#define EVP_CIPHER_CTX_flags(e) ((e)->cipher->flags)

#define EVP_CIPHER_CTX_mode(e) ((e)->cipher->flags & EVP_CIPH_MODE)

int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type);

int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type);

【EVP_CIPHER_CTX_set_padding】

该函数设置是否采用padding功能.在算法缺省的情况下,是使用标准的块padding功

能的,并且在解密的时候会自动接测padding并将它删除。如果将参数pad设置为0,则p adding功能就会被禁止,那么在加密和解密的时候,数据应该为加密块长度的整数倍,

否则就会出错。函数恒返回1。

【EVP_CIPHER_CTX_set_key_length】

该函数进行加密算法结构EVP_CIPHER_CTX密钥长度的设置。如果算法是一个密钥长度固定的算法,那么如果设置的密钥长度跟它固定的长度不一致,就会产生错误。

【EVP_get_cipherbyname, EVP_get_cipherbynid和EVP_get_cipherbyobj】

这三个函数都根据给定的参数返回一个EVP_CIPHER结构,不同的是给定的参数分别

是算法名称、算法的NID和一个ASN1_OBJECT结构。具体的算法名称、NID以及ASN1_OBJE

CT结构请参看object\boject.h文件的定义。

【EVP_CIPHER_nid和EVP_CIPHER_CTX_nid】

这两个函数返回EVP_CIPHER或EVP_CIPHER_CTX结构内部的算法的NID。返回的NID 值

只是一个内部存储的值,并不一定真的有相应的OBJECT定义。

【EVP_CIPHER_key_length和EVP_CIPHER_CTX_key_length】

这两个函数返回EVP_CIPHER或EVP_CIPHER_CTX结构内部的算法的密钥长度。常量EV

P_MAX_KEY_LENGTH定义了所有算法最长的密钥长度。需要注意的是,对于EVP_CIPHER_k

ey_length函数来说,对特定的一种算法密钥长度是不变的,但是EVP_CIPHER_CTX_key_ length函数对同一个算法密钥长度却是可变的。

【EVP_CIPHER_iv_length和EVP_CIPHER_CTX_iv_length】

这两个函数返回EVP_CIPHER或EVP_CIPHER_CTX结构内部的算法的初始化向量长度。如果算法不使用IV,那么就会返回0。常量EVP_MAX_IV_LENGTH定义了所有算法最长的IV

长度

【EVP_CIPHER_block_size和EVP_CIPHER_CTX_block_size】

这两个函数返回EVP_CIPHER或EVP_CIPHER_CTX结构内部的算法的加密块长度。常

EVP_MAX_IV_LENGTH也是所有算法最长的块长度。

【EVP_CIPHER_type和EVP_CIPHER_CTX_type】

这两个函数返回EVP_CIPHER或EVP_CIPHER_CTX结构内部的算法的类型。该类型的值

是算法的NID,一般来说,NID忽略了算法的一些参数,如40位和129位RC2算法的NID 是相

同的。如果算法没有相应定义的NID或者不是ASN1所支持的,那么本函数就会返回NID_u ndef。

【EVP_CIPHER_CTX_cipher】

该函数返回EVP_CIPHER_CTX结构里面的EVP_CIPHER结构。

【EVP_CIPHER_mode和EVP_CIPHER_CTX_mode】

这两个函数返回相应结构算法的块加密模式,包括EVP_CIPH_ECB_MODE, EVP_CIPH_ CBC_MODE, EVP_CIPH_CFB_MODE和EVP_CIPH_OFB_MODE;如果算法是流加密算法,那么就

返回EVP_CIPH_STREAM_CIPHER 。

【EVP_CIPHER_param_to_asn1】

该函数设置算法结构的参数,一般来说设置的值包括了所有参数和一个IV值。如果

算法有IV,那么调用该函数时IV是必须设置的。该函数必须在所设置的算法结构使用之

前(如调用EVP_EncryptUpdate和EVP_DecryptUpdate函数之前)调用。如果ASN1不支持该算法,那么调用该函数将导致失败。操作成功返回1,否则返回0。

【EVP_CIPHER_asn1_to_param】

该函数给用算法结构里面的值设置参数type的结构。其设置的内容由具体的算法决

定。如在RC2算法中,它会设置IV和有效密钥长度。本函数应该在算法结构的基本算法类型已经设置了但是密钥还没有设置之前调用。例如,调用EVP_CipherInit函数的时候使

用参数IV,并将key设置位NULL,然后就应该调用本函数,最后再调用EVP_CipherInit,这时候除了key设置位NULL外所有参数都应该设置。当ASN1不支持不支持该算法或者有参

数不能设置的时候(如RC2的有效密钥长度不支持),该函数调用就会失败。操作成功返

回1,否则返回0。

【EVP_CIPHER_CTX_ctrl】

该函数可以设置不同算法的特定的参数。目前只有RC2算法的有效密钥长度和RC5算

法的加密次数(rounds)可以进行设置。

BTW:我自己感觉都写的有一点慢了,知道大家想知道怎么用来编程,但是,先把这

么多函数介绍清楚了,下面看起来就会轻松多了,下一篇就将介绍EVP_Encrypt*...*系

列函数的编程框架,并举几个例子。

openssl之EVP系列之6---EVP_Encrypt系列函数编程架构及例子

---根据openssl doc\crypto\EVP_EncryptInit.pod和doc\ssleay.txt cipher.doc

部分翻译和自己的理解写成

(作者:DragonKing, Mail: wzhah@https://www.wendangku.net/doc/1f9363347.html, ,发布于:https://www.wendangku.net/doc/1f9363347.html,之

openssl专业论坛,版本:openssl-0.9.7)

在前面的两篇文章,已经对EVP_Encrypt*...*系列函数做了详细的介绍,本章将说

明该系列函数通用的应用架构,并举几个函数应用例子。

【应用架构】

一般来说,EVP_Encrypt*...*系列函数的应用架构如下所描述(假设加密算法为3DE S):

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,i

v);

3.初始加密算法结构EVP_CIPHER_CTX

EVP_EncryptInit_ex(&ctx, EVP_des_ede3_cbc(), NULL, key, iv);

4.进行数据的加密操作

while (....)

{

EVP_EncryptUpdate(ctx,out,&outl,in,512);

}

一般来说采用了循环的结构进行处理,每次循环加密数据为512字节,密文输出到o ut,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 outbuf[1024];

int outlen, tmplen;

//其实key和iv一般应该从别的地方得到,这里固定了至少作为演示使用的

unsigned char key[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

unsigned char iv[] = {1,2,3,4,5,6,7,8};

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

{

/* 出错处理*/

return 0;

}

//注意,传入给下面函数的输出缓存参数必须注意不能覆盖了原来的加密输出的数

if(!EVP_EncryptFinal_ex(&ctx, outbuf + outlen, &tmplen))

{

/* 出错处理*/

return 0;

}

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 01020 30405060708 -d

6.使用文件I/O和80位密钥RC2算法的通用加密解密函数实例,该函数可以进行加密,也可以进行解密,由参数do_encrypt决定,该参数为1时则执行加密,为0时则执行解密。

int do_crypt(FILE *in, FILE *out, int do_encrypt)

{

/*为输出缓冲设置足够的附加空间*/

inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];

int inlen, outlen;

//其实key和iv一般应该从别的地方得到,这里固定了至少作为演示使用的

unsigned char key[] = "0123456789";

unsigned char iv[] = "12345678";

//这时候不进行key和IV的设置,因为我们还要修改参数

EVP_CIPHER_CTX_init(&ctx);

EVP_CipherInit_ex(&ctx, EVP_rc2(), NULL, NULL, NULL, do_encrypt);

EVP_CIPHER_CTX_set_key_length(&ctx, 10);

//完成参数设置,进行key和IV的设置

EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt);

for(;;)

{

inlen = fread(inbuf, 1, 1024, in);

if(inlen <= 0) break;

if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen))

{

/*出错处理 */

return 0;

}

fwrite(outbuf, 1, outlen, out);

}

if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen))

{

/* 出错处理*/

return 0;

}

fwrite(outbuf, 1, outlen, out);

EVP_CIPHER_CTX_cleanup(&ctx);

return 1;

}

openssl之EVP系列之7---信息摘要算法结构概述

---根据openssl doc\crypto\EVP_DigestInit.pod翻译和自己的理解写成

(作者:DragonKing, Mail: wzhah@https://www.wendangku.net/doc/1f9363347.html, ,发布于:https://www.wendangku.net/doc/1f9363347.html,之openssl专业论坛,版本:openssl-0.9.7)

该系列函数封装了openssl加密库所有的信息摘要算法,通过这种EVP封装,当使用不同的信息摘要算法时,只需要对初始化参数修改一下就可以了,其它代码可以完全一样。这些算法包括MD2、MD5以及SHA等算法。

【EVP_MD结构介绍】

所有的算法都维护着下面定义的结构的一个指针,在此基础上实现了算法的功能。该结构EVP_MD如下:

typedef struct env_md_st

{

int type;

int pkey_type;

int md_size;

unsigned long flags;

int (*init)(EVP_MD_CTX *ctx);

int (*update)(EVP_MD_CTX *ctx,const void *data,unsigned long count);

int (*final)(EVP_MD_CTX *ctx,unsigned char *md);

int (*copy)(EVP_MD_CTX *to,const EVP_MD_CTX *from);

int (*cleanup)(EVP_MD_CTX *ctx);

int (*sign)();

int (*verify)();

int required_pkey_type[5]; /*EVP_PKEY_xxx */

int block_size;

int ctx_size;

} EVP_MD;

下面对该结构体的部分参数解释:

type——信息摘要算法的NID标识

pkey_type——是信息摘要-签名算法体制的相应NID标识,如NID_shaWithRSAEncry ption

md_size——是信息摘要算法生成的信息摘要的长度,如SHA算法是SHA_DIGEST_LEN GTH,该值是20

init——指向一个特定信息摘要算法的初始化函数,如对于SHA算法,指针指向SHA

_Init

update——指向一个真正计算摘要值的函数,例如SHA算法就是指向SHA_Update

final——指向一个信息摘要值计算之后要调用的函数,该函数完成最后的一块数据

的处理工作。例如SHA算法就是指向SHA_Final.

copy——指向一个可以在两个EVP_MD_CTX结构之间拷贝参数值的函数

required_pkey_type——指向一个用来签名的算法EVP_PKEY的类型,如SHA算法就指向EVP_PKEY_RSA_method

block_size——一个用来进行信息摘要的输入块的的长度(单位是字节),如SHA算

法就是SHA_CBLOCK

ctx_size——是CTX结构的长度,在SHA算法里面应该就是sizeof(EVP_MD*)+sizeof (SHA_CTX)

如果你要增加新的算法,那么可以定义这个结构,并进行必要的一直,然后就可以

使用通用的函数了。跟EVP_CIPHER系列函数一样,使用这个封装技术,就可以在使用一种摘要算法时,比如MD5,在连接程序的时候就只连接MD5的代码。如果使用证书来标识算法,那么就会导致所有其它的信息摘要算法代码都连接到程序中去了。

【EVP_MD_CTX结构介绍】

在调用函数的时候,一般来说需要传入上面说的type的参数和下面所定义的一个CT

X结构,该结构EVP_MD_CTX定义如下:

typedef struct env_md_ctx_st

{

const EVP_MD *digest;

ENGINE *engine;

unsigned long flags;

void *md_data;

}EVP_MD_CTX ;

该结构的成员解释如下:

digest——指向上面介绍的EVP_MD结构的指针

engine——如果算法由ENGINE提供,该指针指向该ENGINE

md_data——信息摘要数据

【支持的信息摘要算法】

EVP_md_null(void)

EVP_md2(void)

EVP_md4(void)

EVP_md5(void)

EVP_sha(void)

EVP_sha1(void)

EVP_dss(void)

EVP_dss1(void)

EVP_mdc2(void)

EVP_ripemd160(void)

openssl之EVP系列之8---EVP_Digest系列函数详解

---根据openssl doc\crypto\EVP_DigestInit.pod翻译和自己的理解写成

(作者:DragonKing, Mail: wzhah@https://www.wendangku.net/doc/1f9363347.html, ,发布于:https://www.wendangku.net/doc/1f9363347.html,之openssl专业论坛,版本:openssl-0.9.7)

EVP_Digest系列提供了与EVP_Encrypt系列相似的函数,定义如下(openssl/evp.h ):

void EVP_MD_CTX_init(EVP_MD_CTX *ctx);

EVP_MD_CTX *EVP_MD_CTX_create(void);

int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl );

int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);

int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md,

unsigned int *s);

int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);

void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);

int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out,const EVP_MD_CTX *in);

int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);

int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md,

unsigned int *s);

int EVP_MD_CTX_copy(EVP_MD_CTX *out,EVP_MD_CTX *in);

#define EVP_MAX_MD_SIZE (16+20) /* The SSLv3 md5+sha1 type */

#define EVP_MD_type(e) ((e)->type)

#define EVP_MD_pkey_type(e) ((e)->pkey_type)

#define EVP_MD_size(e) ((e)->md_size)

#define EVP_MD_block_size(e) ((e)->block_size)

#define EVP_MD_CTX_md(e) (e)->digest)

#define EVP_MD_CTX_size(e) EVP_MD_size((e)->digest)

#define EVP_MD_CTX_block_size(e) EVP_MD_block_size((e)->digest)

#define EVP_MD_CTX_type(e) EVP_MD_type((e)->digest)

【EVP_MD_CTX_init】

该函数初始化一个EVP_MD_CTX结构。

【EVP_MD_CTX_create】

该函数创建一个EVP_MD_CTX结构,分配内存并进行初始化,返回该结构。

【EVP_DigestInit_ex】

该函数使用参数impl所指向的ENGINE设置该信息摘要结构体,参数ctx在调用本函数之前必须经过初始化。参数type一般是使用象EVP_sha1这样的函数的返回值。如果impl 为NULL,那么就会使用缺省实现的信息摘要函数。大多数应用程序里面impl是设置为NU LL的。操作成功返回1,否则返回0。

【EVP_DigestUpdate】

该函数将参数d中的cnt字节数据进行信息摘要到ctx结构中去,该函数可以被调用多次,用以对更多的数据进行信息摘要。操作成功返回1,否则返回0。

【EVP_DigestFinal_ex】

本函数将ctx结构中的摘要信息数据返回到参数md中,如果参数s不是NULL,那么摘要数据的长度(字节)就会被写入到参数s中,大多数情况瞎,写入的值是EVP_MAX_MD_ SIZE。在调用本函数后,不能使用相同的ctx结构调用EVP_DigestUpdate再进行数据的信息摘要操作,但是如果调用EVP_DigestInit_ex函数重新初始化后可以进行新的信息摘要

操作。操作成功返回1,否则返回0。

【EVP_MD_CTX_cleanup】

清除一个信息摘要结构,该函数应该在一个信息摘要结构使用后不再需要的时候调

用。

【EVP_MD_CTX_destroy】

清除信息摘要结构并释放所有分配的内存空间,只有使用EVP_MD_CTX_create函数创建的信息摘要结构才能使用该函数进行释放。

【EVP_MD_CTX_copy_ex】

该函数可以用来将信息摘要数据从in结构拷贝到out结构中。如果有大量的数据需要

进行信息摘要,而且这些数据只有最后几个字节不同的时候,使用该函数就显得特别有用,节省时间。其中,out结构必须在调用本函数之前进行初始化。操作成功返回1,否

则返回0。

【EVP_DigestInit】

该函数功能跟EVP_DigestInit_ex函数相同,但是ctx参数可以不用初始化,而且该

函数只使用缺省实现的算法。

【EVP_DigestFinal】

该函数功能跟EVP_DigestFinal_ex函数相同,但是ctx结构会自动清除。一般来说,

现在新的程序应该使用EVP_DigestInit_ex和EVP_DigestFinal_ex函数,因为这些函数可

以在使用完一个EVP_MD_CTX结构后,不用重新声明和初始化该结构就能使用它进行新的数据处理,而且新的带_ex的函数也可以使用非缺省的实现算法库。

【EVP_MD_CTX_copy】

该函数跟EVP_MD_CTX_copy_ex函数功能相同,但是out参数可以不用初始化。【EVP_MD_size和EVP_MD_CTX_size】

这两个函数返回结构里面摘要信息的长度。

【EVP_MD_block_size和EVP_MD_CTX_block_size】

这两个函数返回摘要信息块处理的长度。

【EVP_MD_type和EVP_MD_CTX_type】

这两个函数返回信息摘要结构算法的NID。例如,EVP_MD_type(EVP_sha1())返回NI

D_sha1。该函数通常在设置ASN1 OID的时候使用。如果算法不存在,返回NID_undef。【EVP_MD_CTX_md】

该函数返回给定EVP_MD_CTX结构里面的EVP_MD结构。

【EVP_MD_pkey_type】

该函数返回信息摘要结构里面公钥签名算法的NID。例如,如果EVP_sha1是使用RSA 签名算法,那么就会返回NID_sha1WithRSAEncryption。

【EVP_md2、EVP_md5、EVP_sha、EVP_sha1、EVP_mdc2和EVP_ripemd160】

这些函数返回相应名字的EVP_MD结构,它们都使用RSA算法作为签名算法。在新的程序里,一般推荐使用sha1算法。

【EVP_dss和EVP_dss1】

这两个函数返回的EVP_MD结构分别使用sha和sha1信息摘要算法,但是签名算法使用DSS(DSA)。

【EVP_md_null】

该函数返回的信息摘要结构不作任何事情,返回的摘要信息长度为0。

【EVP_get_digestbyname、EVP_get_digestbynid和EVP_get_digestbyobj】

这三个函数分别根据给定的算法名称、算法NID以及ASN1_OBJECT结构返回一个相应的EVP_MD算法结构。摘要算法在使用之前必须进行初始化,如使用Openssl_add_all_di gests进行初始化。如果调用不成功,返回NULL。

openssl之EVP系列之9---EVP_Digest系列函数的一个例子

---根据openssl doc\crypto\EVP_DigestInit.pod翻译

(作者:DragonKing, Mail: wzhah@https://www.wendangku.net/doc/1f9363347.html, ,发布于:https://www.wendangku.net/doc/1f9363347.html,之

openssl专业论坛,版本:openssl-0.9.7)

本例子是openssl帮助文档提供的。该例子根据命令行输入的信息摘要算法名字对" Test Message\n"和"Hello World\n"字符串进行信息摘要操作。

#include

#include

main(int argc, char *argv[])

{

EVP_MD_CTX mdctx;

const EVP_MD *md;

char mess1[] = "Test Message\n";

char mess2[] = "Hello World\n";

unsigned char md_value[EVP_MAX_MD_SIZE];

int md_len, i;

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

OpenSSL_add_all_digests();

if(!argv[1]) {

printf("Usage: mdtest digestname\n");

exit(1);

}

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

md = EVP_get_digestbyname(argv[1]);

if(!md) {

printf("Unknown message digest %s\n", argv[1]);

exit(1);

}

//初始化信息摘要结构mdctx,这在调用EVP_DigestInit_ex函数的时候是必须的。

EVP_MD_CTX_init(&mdctx);

//使用md的算法结构设置mdctx结构,impl为NULL,即使用缺省实现的算法(open ssl本身提供的信息摘要算法)

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("\n");

}

openssl之EVP系列之10---EVP_Sign系列函数介绍

---根据openssl doc\crypto\EVP_SignInit.pod翻译

(作者:DragonKing, Mail: wzhah@https://www.wendangku.net/doc/1f9363347.html, ,发布于:https://www.wendangku.net/doc/1f9363347.html,之

openssl专业论坛,版本:openssl-0.9.7)

EVP_Sign系列函数使用的基础结构跟信息摘要算法使用的基础结构是一样的,而且

,其前面的两个操作步骤初始化和数据操作(信息摘要)也跟信息摘要算法是一样的,唯一不一样的是最后一步操作,本系列函数做了签名的工作,而信息摘要系列函数当然就只是简单的处理完摘要信息了事了。其实这是很容易理解的事情,因为签名算法就是在信息摘要之后用私钥进行签名的过程。本系列函数定义的如下(openssl\evp.h):

int EVP_SignInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);

int EVP_SignUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);

int EVP_SignFinal(EVP_MD_CTX *ctx,unsigned char *sig,unsigned int *s, E

VP_PKEY *pkey);

void EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type);

int EVP_PKEY_size(EVP_PKEY *pkey);

【EVP_SignInit_ex】

该函数是一个宏定义函数,其实际定义如下:

#define EVP_SignInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c)

可见,该函数跟前面叙述的EVP_DigestInit_ex的功能和使用方法是一样的,都是使

用ENGINE参数impl所代表的实现函数功能来设置结构ctx。在调用本函数前,参数ctx一定要经过EVP_MD_CTX_init函数初始化。详细使用方法参看前面的文章介绍。成功返回1 ,失败返回0。

【EVP_SignUpdate】

该函数也是一个宏定义函数,其实际定义如下:

#define EVP_SignUpdate(a,b,c) EVP_DigestUpdate(a,b,c)

该函数使用方法和功能也跟前面介绍的EVP_DigestUpdate函数一样,将一个cnt字节

的数据经过信息摘要运算存储到结构ctx中,该函数可以在一个相同的ctx中调用多次来

实现对更多数据的信息摘要工作。成功返回1,失败返回0。

【EVP_SignFinal】

该函数跟前面两个函数不同,这是签名系列函数跟信息摘要函数开始不同的地方,

其实,该函数是将签名操作的信息摘要结构ctx拷贝一份,然后调用EVP_DigestFinal_e

x完成信息摘要工作,然后开始对摘要信息用私钥pkey进行签名,并将签名信息保存在参

数sig里面。如果参数s不为NULL,那么就会将签名信息数据的长度(单位字节)保存在该参数中,通常写入的数据是EVP_PKEY_size(key)。

因为操作的时候是拷贝了一份ctx,所以,原来的ctx结构还可以继续使用EVP_Sign Update和EVP_SignFinal函数来完成更多信息的签名工作。不过,最后一定要使用EVP_M D_CTX_cleanup函数清除和释放ctx结构,否则就会造成内存泄漏。

此外,当使用DSA私钥签名的时候,一定要对产生的随机数进行种子播种工作(see ded),否则操作就会失败。RSA算法则不一定需要这样做。至于使用的签名算法跟摘要算法的关系,在EVP_Digest系列中已经有详细说明,这里不再重复。

本函数操作成功返回1,否则返回0。

【EVP_SignInit】

本函数也是一个宏定义函数,其定义如下:

#define EVP_SignInit(a,b) EVP_DigestInit(a,b)

所以其功能和用法跟前面介绍的EVP_DigestInit函数完全一样,使用缺省实现的算

法初始化算法结构ctx。

【EVP_PKEY_size】

本函数返回一个签名信息的最大长度(单位字节)。实际签名信息的长度则由上述

的函数EVP_SignFinal返回,有可能比这小。

上述所有函数发生错误,可以使用ERR_get_error函数获得错误码。

openssl之EVP系列之11---EVP_Verify系列函数介绍

---根据openssl doc\crypto\EVP_VerifyInit.pod翻译和自己的理解写成

(作者:DragonKing, Mail: wzhah@https://www.wendangku.net/doc/1f9363347.html, ,发布于:https://www.wendangku.net/doc/1f9363347.html,之

openssl专业论坛,版本:openssl-0.9.7)

跟EVP_Sign系列函数一样,EVP_Verify系列函数的前两步(初始化和信息摘要处理

)跟信息摘要算法是一样的,因为签名验证的过程就是先对信息进行信息摘要,然后再

将发来的摘要信息解密后进行比较的过程,其定义如下(openssl\evp.h):

int EVP_VerifyInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl

);

int EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);

int EVP_VerifyFinal(EVP_MD_CTX *ctx,unsigned char *sigbuf, unsigned int

siglen,EVP_PKEY *pkey);

int EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type);

【EVP_VerifyInit_ex】

该函数是一个宏定义函数,其实际定义如下:

#define EVP_VerifyInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c)

所以,其功能和使用方法跟前面介绍的EVP_DigestInit_ex函数是一样的。该函数使

用参数impl所提供的算法库对验证结构ctx进行设置。在调用本函数之前,参数ctx必须经过调用EVP_MD_CTX_init进行初始化。成功返回1,失败返回0。

【EVP_VerifyUpdate】

该函数也是一个宏定义函数,其实际定义如下:

#define EVP_VerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c)

所以,其功能和使用方法跟前面介绍的EVP_DigestUpdate函数是相同的。该函数将

参数d中的cnt字节数据经过信息摘要计算后保存到ctx中,该函数可以进行多次调用,以处理更多的数据。成功调用返回1,失败返回0。

【EVP_VerifyFinal】

该函数使用公钥pkey和ctx结构里面的信息验证sigbuf里面的数据的签名。事实上,

该函数先调用EVP_MD_CTX_copy_ex函数将原来的ctx拷贝一份,然后调用EVP_DigestFin al_ex函数完成拷贝的ctx的信息摘要计算,最后才使用公钥进行签名的验证工作。

因为该函数实际上处理的是原来ctx函数的一个拷贝,所以原来的ctx结构还可以调

用EVP_VerifyUpdate和EVP_VerifyFinal函数进行更多的数据处理和签名验证工作。

在使用完之后,ctx必须使用EVP_MD_CTX_cleanup函数释放内存,否则就会导致内存泄漏。

此外,至于信息摘要算法和签名算法的关联的关系,请参照信息摘要算法部分的说

明。

该函数调用成功返回1,失败则返回0或-1。

【EVP_VerifyInit】

该函数使用缺省的实现算法对ctx结构进行初始化。也是一个宏定义函数,其定义如下:

#define EVP_VerifyInit(a,b) EVP_DigestInit(a,b)

所以跟EVP_DigestInit函数功能和用法是一样的。

openssl之EVP系列之12---EVP_Seal系列函数介绍

---根据openssl doc\crypto\EVP_SealInit.pod翻译和自己的理解写成

(作者:DragonKing, Mail: wzhah@https://www.wendangku.net/doc/1f9363347.html, ,发布于:https://www.wendangku.net/doc/1f9363347.html,之

openssl专业论坛,版本:openssl-0.9.7)

改系列函数是相当于完成一个电子信封的功能,它产生一个随机密钥,然后使用一

Openssl生成证书步骤说明

Openssl生成证书步骤说明 命令操作: 1、生成普通私钥: 2、生成带加密口令的密钥: 在生成带加密口令的密钥时需要自己去输入密码。对于为密钥加密现在提供了一下几种算 通过生成的私钥去生成证书:

在生成证书的时候需要按照提示输入一些个人信息。 通过私钥生成公钥: 格式转换:(证书、私钥、公钥)(PEM <----->DER) 从DER格式转换成PEM格式一样,就是把inform的格式改成DERoutform的格式改成PEM 即可。 服务器和客户端认证的证书生成 下面是一个服务器和客户端认证的证书、私钥生成方法:(server.crt、client.crt、ca.crt) 用默认openssl配置文件生成证书,先创建文件夹 创建文件夹demoCA/newcerts: mkdir -p demoCA/newcerts 创建个空文件index.txt: touch demoCA/index.txt 向文件serial中写入01: echo 01 > demoCA/serial 1.首先要生成服务器端的私钥(key 文件): openssl genrsa -des3 -out server.key 1024 运行时会提示输入密码,此密码用于加密key 文件(参数des3 便是指加密算法,当然也可以选用其他你认 为安全的算法.),以后每当需读取此文件(通过openssl 提供的命令或API)都需输入口令.如果觉得不方 便,也可以去除这个口令,但一定要采取其他的保护措施!

去除key 文件口令的命令: openssl rsa -in server.key -out server.key 2.openssl req -new -key server.key -out server.csr 生成Certificate Signing Request(CSR),生成的csr 文件交给CA 签名后形成服务端自己的证书. 屏幕上将有提示,依照其指示一步一步输入要求的个人信息即可. 3.对客户端也作同样的命令生成key 及csr 文件: openssl genrsa -des3 -out client.key 1024 openssl req -new -key client.key -out client.csr 4.CSR 文件必须有CA 的签名才可形成证书.可将此文件发送到verisign 等地方由它验证,要交一大笔钱, 何不自己做CA 呢. openssl req -new -x509 -keyout ca.key -out ca.crt 5.用生成的CA 的证书为刚才生成的server.csr,client.csr 文件签名: openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key openssl ca -in client.csr -out client.crt -cert ca.crt -keyfile ca.key 现在我们所需的全部文件便生成了. 另: client 使用的文件有:ca.crt,client.crt,client.key server 使用的文件有:ca.crt,server.crt,server.key .crt 文件和.key 可以合到一个文件里面,本人把2 个文件合成了一个.pem 文件(直接拷贝过去就行了)

自签名OpenSSL证书流程

自签名OpenSSL证书流程 1.首先要生成服务器端的私钥(key文件): openssl genrsa -des3 -out server.key 1024 运行时会提示输入密码,此密码用于加密key文件(参数des3便是指加密算法,当然也可以选用其他你认为安全的算法.),以后每当需读取此文件(通过openssl提供的命令或API)都需输入口令.如果觉得不方便,也可以去除这个口令,但一定要采取其他的保护措施! 去除key文件口令的命令: openssl rsa -in server.key -out server.key [生成过程中提示需要输入私钥的密码,现设为111111] 2.openssl req -new -key server.key -out server.csr -config https://www.wendangku.net/doc/1f9363347.html,f 生成Certificate Signing Request(CSR),生成的csr文件交给CA签名后形成服务端自己的证书.屏幕上将有提示,依照其指示一步一步输入要求的个人信息即可. [利用私钥生成CA的证书请求,在这个过程中,按步骤提示输入各种信息,注意前面国家、州等信息和以后生成客户端.csr文件等,需要填入的信息时,需要保持一致,否则验证会通不过] Country Name(只能填2个字母) : cn State or Province Name : sz Locality Name : ns Organization Name : vc Organization Unit Name : odc Common Name : rome Email Address : rome80@https://www.wendangku.net/doc/1f9363347.html,(邮箱名可以不一样,可以区别不同的证书) 其中有一个A challenge password,不知道做什么用,填111111 An optional company name : milano -config https://www.wendangku.net/doc/1f9363347.html,f是配置文件信息 在生成.csr和证书的.crt时,都要填入上述信息 3.对客户端也作同样的命令生成key及csr文件: openssl genrsa -des3 -out client.key 1024 openssl req -new -key client.key -out client.csr -config https://www.wendangku.net/doc/1f9363347.html,f 4.openssl genrsa -des3 -out ca.key 1024 [这步是自己加上去的,先生成ca的私钥]

使用OpenSSL建立根CA及自签名证书制作过程

使用OpenSSL建立根CA及自签名证书制作过程 2009-12-24 11:35:32| 分类:openssl |字号订阅 Openssl版本:0.9.8 版本,可从https://www.wendangku.net/doc/1f9363347.html,处下载。 1.先建立如下目录结构: $home/testca # testca 是待建CA的主目录 ├─newcerts/ # newcerts子目录将存放CA签发过的数组证书(备份目录) ├─private/ # private目录用来存放CA私钥 └─conf/ # conf目录用来存放简化openssl命令行参数用的配置文件 此外使用命令 echo "01" > serial touch index.txt 在ca根目录下创建文件serial (用来存放下一个证书的序列号) 和indext.txt (证书信息数据库文件)。 1.生成CA的私钥和自签名证书 (根证书) 创建配置文件:vi "$HOME/testca/conf/gentestca.conf" 文件内容如下: #################################### [ req ] default_keyfile = /home/cx/testCA/private/cakey.pem default_md = md5 prompt = no

distinguished_name = ca_distinguished_name x509_extensions = ca_extensions [ ca_distinguished_name ] organizationName = ss organizationalUnitName = sstc commonName = sstcCA emailAddress = GChen2@https://www.wendangku.net/doc/1f9363347.html, #自己的邮件地址 [ ca_extensions ] basicConstraints = CA:true ######################################## 然后执行命令如下: cd "$HOME/testca" openssl req -x509 -newkey rsa:2048 -out cacert.pem -outform PEM -days 2190 -config "$HOME/testca/conf/gentestca.conf" 执行过程中需要输入CA私钥的保护密码,假设我们输入密码: 888888 可以用如下命令查看一下CA自己证书的内容 openssl x509 -in cacert.pem -text –noout 创建一个配置文件,以便后续CA日常操作中使用 vi "$HOME/testca/conf/testca.conf"

Linux下利用openssl 生成SSL证书步骤

Linux下利用openssl 生成SSL证书步骤 1、概念 首先要有一个CA根证书,然后用CA根证书来签发用户证书。 用户进行证书申请:一般先生成一个私钥,然后用私钥生成证书请求(证书请求里应含有公钥信息),再利用证书服务器的CA根证书来签发证书。 2、后缀详解 .key格式:私有的密钥 .csr格式:证书签名请求(证书请求文件),含有公钥信息,certificate signing request 的缩写 .crt格式:证书文件,certificate的缩写 .crl格式:证书吊销列表,Certificate Revocation List的缩写 .pem格式:用于导出,导入证书时候的证书的格式,有证书开头,结尾的格式 3、添加 index.txt 和 serial 文件 cd /etc/pki/CA/ touch /etc/pki/CA/index.txt touch /etc/pki/CA/serial echo 01 > /etc/pki/CA/serial 4、CA根证书的生成 4.1 生成CA私钥(.key) openssl genrsa -out ca.key 2048 [root@CA]# openssl genrsa -out ca.key 2048 Generating RSA private key, 2048 bit long modulus .............+++ .....+++ e is 65537 (0x10001) 4.2 生成CA证书请求(.csr) openssl req -new -key ca.key -out ca.csr [root@CA]# openssl req -new -key ca.key -out ca.csr You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value,

OpenSSL证书制作过程

比亚迪培训讲义 在J2EE中使用数字证书 深圳市金蝶中间件有限公司 2007年12月

Table of Contents 1 数字证书使用的场合 (3) 2 数字证书的颁发 (3) 2.1 概述 (3) 2.2 创建自签名CA (3) 2.2.1 生成ca私钥 (3) 2.2.2 生成ca待签名证书 (4) 2.2.3用CA私钥进行自签名,得到自签名的CA根证书 (4) 2.2.4 https://www.wendangku.net/doc/1f9363347.html,f配置文档 (5) 2.3 颁发服务器证书 (7) 2.3.1 生成服务器私钥对及自签名证书 (7) 2.3.2 生成服务器待签名证书 (7) 2.3.3 请求CA签名服务器待签名证书,得到经CA签名的服务器证书 (8) 2.3.4把CA根证书导入密钥库 mykeystore (8) 2.3.5把经过CA签名的服务器证书导入密钥库mykeystore (8) 2.4 颁发客户端证书 (9) 2.4.1 生成客户端私钥 (9) 2.4.2生成客户端待签名证书 (9) 2.4.3请求CA签名客户端待签名证书,得到经CA签名的客户端证书 (10) 生成客户端的个人证书client.p12 (10) 2.5 CA根证书导入客户端 (11) 2.6个人证书导入客户端 (11) 3 在J2EE中使用证书 (11) 3.1 配置SSL双向认证 (11) 3.1.1 服务器端密钥库和信任库 (12) 3.1.2修改Muxer服务 (12) 3.1.3修改SecurityService服务 (13) 3.2 在程序中获取证书信息 (13) 4 练习 (13) 5 附录 (14) 5.1 SSL v3的处理步骤 (14) 5.2 命令行调试SSL证书 (14)

openssl使用手册

OpenSSL有两种运行模式:交互模式和批处理模式。 直接输入openssl回车进入交互模式,输入带命令选项的openssl进入批处理模式。 (1) 配置文件 OpenSSL的默认配置文件位置不是很固定,可以用openssl ca命令得知。 你也可以指定自己的配置文件。 当前只有三个OpenSSL命令会使用这个配置文件:ca, req, x509。有望未来版本会有更多命令使用配置文件。 (2)消息摘要算法 支持的算法包括:MD2, MD4, MD5, MDC2, SHA1(有时候叫做DSS1), RIPEMD-160。SHA1和RIPEMD-160产生160位哈西值,其他的产生128位。除非出于兼容性考虑,否则推荐使用SHA1或者RIPEMD-160。 除了RIPEMD-160需要用rmd160命令外,其他的算法都可用dgst命令来执行。 OpenSSL对于SHA1的处理有点奇怪,有时候必须把它称作DSS1来引用。 消息摘要算法除了可计算哈西值,还可用于签名和验证签名。签名的时候,对于DSA生成的私匙必须要和DSS1(即SHA1)搭配。而对于RSA生成的私匙,任何消息摘要算法都可使用。 ############################################################# # 消息摘要算法应用例子 # 用SHA1算法计算文件file.txt的哈西值,输出到stdout $ openssl dgst -sha1 file.txt # 用SHA1算法计算文件file.txt的哈西值,输出到文件digest.txt $ openssl sha1 -out digest.txt file.txt # 用DSS1(SHA1)算法为文件file.txt签名,输出到文件dsasign.bin # 签名的private key必须为DSA算法产生的,保存在文件dsakey.pem中 $ openssl dgst -dss1 -sign dsakey.pem -out dsasign.bin file.txt # 用dss1算法验证file.txt的数字签名dsasign.bin, # 验证的private key为DSA算法产生的文件dsakey.pem $ openssl dgst -dss1 -prverify dsakey.pem -signature dsasign.bin file.txt # 用sha1算法为文件file.txt签名,输出到文件rsasign.bin # 签名的private key为RSA算法产生的文件rsaprivate.pem $ openssl sha1 -sign rsaprivate.pem -out rsasign.bin file.txt # 用sha1算法验证file.txt的数字签名rsasign.bin, # 验证的public key为RSA算法生成的rsapublic.pem $ openssl sha1 -verify rsapublic.pem -signature rsasign.bin file.txt (3) 对称密码 OpenSSL支持的对称密码包括Blowfish, CAST5, DES, 3DES(Triple DES), IDEA, RC2, RC4以及RC5。OpenSSL 0.9.7还新增了AES的支持。很多对称密码支持不同的模式,包括CBC, CFB, ECB以及OFB。对于每一种密码,默认的模式总是CBC。需要特别指出的是,尽量避免使用ECB模式,要想安全地使用它难以置信地困难。 enc命令用来访问对称密码,此外还可以用密码的名字作为命令来访问。除了加解密,base64可作为命令或者enc命令选项对数据进行base64编码/解码。 当你指定口令后,命令行工具会把口令和一个8字节的salt(随机生成的)进行组合,然后计算MD5 hash值。这个hash值被切分成两部分:加密钥匙(key)和初始化向量(initialization

OpenSSL 命令常用证书操作

在OpenSSL开发包中,包含一个实用工具:openssl,比如我用MinGW GCC 编译OpenSSL 0.9.8k 后,openssl 就保存在out目录下。openssl 工具是完成密钥、证书操作和其它SSL 事务的入口环境,直接运行不带参数的openssl 命令后,可以得到一个shell 环境,在其中可以以交互的方式完成SSL 相关的安全事务。 不过有时,如果用一个带参数选项的openssl 命令完成操作,会更方便。下面是我使用openssl 做证书操作时,记录的常用命令用法。 1.生成密钥 生成RSA密钥,保存在file.key中,命令如下: 上面命令的含义是:产生RSA密钥,包括:私钥和公钥两部分,然后使用DES3算法,用用户输入的密码(passphrase)加密该密钥数据,保存在file.key中。 file.key默认以BASE64方式编码密钥数据,file.key的格式称为:PEM (Privacy Enhanced Mail)格式,在RFC 1421到RFC 1424中定义,PEM是早期用来进行安全电子邮件传输的标准,但现在广泛用在证书、证书请求、PKCS#7对象的存储上,所以证书文件也经常以.pem为扩展名。 2.不加密的密钥 如果在生成密钥时,使用了-des3等加密选项,则会生成被用户密码保护的加密密钥,以增强密钥数据的保密性(因为密钥文件中包含私钥部分)。但有时为了方便,需要不加密的明文密钥(这样安全性会降低),比如:使用

Apache的HTTPS服务,每次启动Apache服务时,都需要用户输入保护密钥的密码,感觉麻烦的话,可以使用明文密钥。 明文密钥可以使用不带-des3等加密选项的openssl命令生成,还可以使用以下命令将加密保护的密钥转换成明文密钥,当然转换过程需要用户输入原来的加密保护密码: 3.查看密钥 查看保存在file.key中的RSA密钥的细节,如果此文件是加密保护的,会提示用户输入加密此文件的密码,命令如下: 输出的内容均是RSA密钥数据的数学信息(模数、指数、质数等),从输出的结果中也可知file.key保存的RSA密钥数据包括:私钥和公钥两部分。 该命令也能查看其它工具生成的密钥,比如SSH,只要密钥文件符合openssl支持的格式。 4.生成证书请求 由file.key产生一个证书请求(Certificate Request),保证在file.csr 中,命令如下: 指定时,默认会访问Unix格式的默认路径:/usr/local/ssl/https://www.wendangku.net/doc/1f9363347.html,f。 创建证书请求时,会要求用户输入一些身份信息,示例如下:

openssl安装及使用

Openssl安装及使用 一软件 Windows下需要用到的软件 1.ActivePerl 一个perl脚本解释器。其包含了包括有Perl for Win32、Perl for ISAPI、PerlScript、Perl Package Manager四套开发工具程序,可以让你编写出适用于unix,windows,linux系统的CGI程序来。安装的只是perl的一个解释程序啦,外观上也不会发生什么变化,你在windows的cmd界面里输入perl -v可查看你所安装的版本。 在你编译perl程序时会用到它。 2.C++编译器 编译器就是将“高级语言”翻译为“机器语言(低级语言)” 的程序。一个现代编译器的主要工作流程:源代码(source code) →预处理器(preprocessor) →编译器(compiler) →汇编程序(assembler) →目标代码(object code) →链接器(Linker) →可执行程序(executables)。c++编译器是一个与标准化C++高度兼容的编译环境。这点对于编译可移植的代码十分重要。编译器对不同的CPU会进行不同的优化。 3.OpenSSL OpenSSL是一个强大的安全套接字层密码库,Apache使用

它加密HTTPS,OpenSSH使用它加密SSH,它还是一个多用途的、跨平台的密码工具。 OpenSSL整个软件包大概可以分成三个主要的功能部分:密码算法库、SSL协议库以及应用程序。OpenSSL的目录结构自然也是围绕这三个功能部分进行规划的。作为一个基于密码学的安全开发包,OpenSSL提供的功能相当强大和全面,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,并提供了丰富的应用程序供测试或其它目的使用。 4.MASM 8.0 MASM是微软公司开发的汇编开发环境,拥有可视化的开发界面,使开发人员不必再使用DOS环境进行汇编的开发,编译速度快,支持80x86汇编以及Win32Asm是Windows下开发汇编的利器。它与windows平台的磨合程度非常好,但是在其他平台上就有所限制,使用MASM的开发人员必须在windows下进行开发。8.0版本在编译OpenSSL的时候不容易出错。 用winrar解压缩MASMSetup.exe得到:setup.exe继续用winrar解压缩setup.exe 得到:vc_masm1.cab继续用winrar解压缩vc_masm1.cab得到:FL_ml_exe__..... (很长的文件名,省略),将这个文件重命名为ml.exe测试得到的ml.exe , 应该显示:Microsoft (R) Macro Assembler Version 8.00.50727.104将ml.exe 拷贝到工作目录,即可正常使用。 5.mspdb60.dll

利用openSSL实现SSl双向认证学习笔记

SSl双向认证学习笔记 2010-09-02 13:16:39| 分类:ssl | 标签:|字号大中小订阅 url]https://www.wendangku.net/doc/1f9363347.html,/sunyujia/archive/2008/10/03/3014667.aspx[/url] [url]https://www.wendangku.net/doc/1f9363347.html,/nataka/archive/2005/09/03/470539.aspx[/url] [url]https://www.wendangku.net/doc/1f9363347.html,/thread-743287-1-1.html[/url] 第一节基础知识 最近要做一个SSL的应用,先后了解了两个命令,一个是keytool,一个是openssl。keytool是JDK得集成环境 。只要安装了JDK,基本上都会有(^_^,除非你安装太老的!),我用的1.5。在安装openssl的时候,花了半天时间 。 用SSL进行双向身份验证意思就是在客户机连接服务器时,链接双方都要对彼此的数字证书进行验证,保证这 是经过授权的才能够连接(我们链接一般的SSL时采用的是单向验证,客户机只验证服务器的证书,服务器不验证客户 机的证书。而连接网上银行时使用的U盾就是用来存储进行双向验证所需要的客户端证书的)。 JDK工具KEYTOOL -genkey 在用户主目录中创建一个默认文件".keystore",还会产生一个mykey的别名,mykey中包含用户的公钥 、私钥和证书 -alias 产生别名 -keystore 指定密钥库的名称(产生的各类信息将不在.keystore文件中 -keyalg 指定密钥的算法 -validity 指定创建的证书有效期多少天 -keysize 指定密钥长度 -storepass 指定密钥库的密码 -keypass 指定别名条目的密码 -dname 指定证书拥有者信息例如:"CN=firstName,OU=org,O=bj,L=bj,ST=gd,C=cn" -list 显示密钥库中的证书信息keytool -list -v -keystore 别名-storepass .... -v 显示密钥库中的证书详细信息 -export 将别名指定的证书导出到文件keytool -export -alias 别名-file 文件名.crt -file 参数指定导出到文件的文件名 -delete 删除密钥库中某条目keytool -delete -alias 别名-keystore sage -keypasswd 修改密钥库中指定条目口令keytool -keypasswd -alias 别名-keypass .... -new .... -storepass ... -keystore 别名 -import 将已签名数字证书导入密钥库keytool -import -alias 别名-keystore 证书名-file 文件名 (可以加.crt 后缀) 命令: 生成证书 keytool -genkey -keystore 文件名(可包含路径) -keyalg rsa -alias 别名-validity 有效期 查看证书 keytool -list -v -keystore 路径 把证书导出到文件 keytool -export -alias 别名-keystore 证书名-rfc -file 文件名(可包含路径) 修改密码 keytool -keypasswd -alias 别名-keypass 旧密码-new 新密码 导出证书到新的TrustStore keytool -import -alias 别名-file 文件名-keystore truststore 此处省略3000字,待补^_^

linux下利用openssl来实现证书的颁发(详细步骤)

linux下利用openssl来实现证书的颁发(详细步骤) 1、首先需要安装openssl,一个开源的实现加解密和证书的专业系统。在centos下可以利用yum安装。 2、openssl的配置文件是https://www.wendangku.net/doc/1f9363347.html,f,我们一般就是用默认配置就可以。如果证书有特殊要求的话,可以修改配置适应需求。这样必须把相关的文件放到配置文件指定的目录下面。 3、首先需要利用openssl生成根证书,以后的服务器端证书或者客户端证书都用他来签发,可以建立多个根证书,就像对应不同的公司一样 #生成根证书的私钥 openssl genrsa -out /home/lengshan/ca.key #利用私钥生成一个根证书的申请,一般证书的申请格式都是csr。所以私钥和csr一般需要保存好openssl req -new -key /home/lengshan/ca.key -out /home/lengshan/ca.csr #自签名的方式签发我们之前的申请的证书,生成的证书为ca.crt openssl x509 -req -days 3650 -in /home/lengshan/ca.csr -signkey /home/lengshan/ca.key -out /home/lengshan/ca.crt #为我们的证书建立第一个序列号,一般都是用4个字符,这个不影响之后的证书颁发等操作 echo FACE > /home/lengshan/serial #建立ca的证书库,不影响后面的操作,默认配置文件里也有存储的地方 touch /home/lengshan/index.txt #建立证书回收列表保存失效的证书

Linux怎么使用OpenSSL命令行

Linux怎么使用OpenSSL命令行 OpenSSL是一款命令行工具可以用来做检测,加密解密等等,尤其在Linux中很实用。那么Linux要如何使用OpenSSL命令行呢?下面小编将针对OpenSSL命令行的使用给大家做个详细介绍。 Linux如何使用OpenSSL命令行 1. base64编码/解码 谈到命令行下如何发送邮件附件,很多人想起了uuencode。也可以使用base64编码。以下是openssl base64编码/解码的使用: $ openssl base64 《filename.bin 》filename.txt $ openssl base64 -d 《filename.txt 》filename.bin 2. 校验文件的一致性

UNIX下校验文件一致性的方法很多,比如sum、cksum、md5sum、sha1sum等。sum和cksum适用于简单校验的场合,生成的校验码容易重复。md5sum有安全漏洞,当前比较推荐的是sha1sum。不过sha1sum在不同的平台用法有些不同。考虑到跨平台性,建议用openssl。 $ openssl sha1 filename SHA1(filename)= e83a42b9bc8431a6645099be50b6341a35d3dceb $ openssl md5 filename MD5(filename)= 26e9855f8ad6a5906fea121283c729c4 3. 文件加密/解密 OpenSSL支持很多加密算法,不过一些算法只是为了保持向后兼容性,现在已不推荐使用,比如DES和RC4-40。推荐使用的加密算法是bf(Blowfish)和-aes-128-cbc(运行在CBC模式的128

OpenSSL来制作证书,在IIS中配置HTTPS(SSL)笔记

info@https://www.wendangku.net/doc/1f9363347.html, 使用OpenSSL来制作证书,在IIS中配置HTTPS(SSL)笔记 下载Win32编译的openssl版本0.9.8e. 1.获取IIS证书请求:打开IIS,右键单击【默认网站】,在【目录安全性】选项卡中点击【服务器证书】按钮,【下一步】,【新建证书】,【现在准备证书请求--下一步】,输入【名称】,输入【单位】和【部门】,输入【公用名称】,选择【国家】并输入【省】和【市县】并【下一步】,【下一步】,【下一步】,【完成】,IIS的证书请求已经获取,就是C:\certreq.txt。这里请牢记输入的信息。 2.准备openssl工作环境:把openssl(编译后的版本)解压到D:\OpenSSL-0.9.8e\下, 在bin目录下建立目录demoCA,在demoCA下建立private和newcerts目录, 并新建index.txt,内容为空 如果没有serial文件,则到openssl网站上下载openssl的源文件,解压后,到apps\demoCA下,拷贝serial文件过来,两个目录两个文件都放到新建的 demoCA下。 3.生成自签名根证书: openssl req -x509 -newkey rsa:1024 -keyout ca.key -out ca.cer -days 3650 -config D:\OpenSSL-0.9.8e\https://www.wendangku.net/doc/1f9363347.html,f PEM pass phrase: password // 根证书私钥密码 Verifying - Enter PEM pass phrase: password Country Name: CN // 两个字母的国家代号 State or Province Name: HB // 省份名称 Locality Name: WUHAN // 城市名称 Organization Name: Skyworth TTG // 公司名称 Organizational Unit Name: Service // 部门名称 Common Name: https://www.wendangku.net/doc/1f9363347.html, // 你的姓名(要是生成服务器端的证书一定要输入域名或者ip地址) Email Address: admin@https://www.wendangku.net/doc/1f9363347.html, // Email地址

openssl工具使用简介

openssl工具使用简介 1.私有密钥生成方法 生成私有密钥,可以使用不同的数字签名算法.下面分别介绍; #采用DSA算法 $ openssl dsaparam -noout -out dsakey0.pem -genkey 1024 #采用RSA算法 $ openssl genrsa -out rsakey0.pem 1024 #采用RSA算法,并使用密码保护.在生成私钥时,需要输入一个密码,用于保护私钥. #在使用这个私钥进行加/解密操作时,也需要输入这个密码. $ openssl genrsa -des3 -out rsakey1.pem 1024 2.公用密钥的生成方法 根据私钥来生成公钥 #生成dsa算法的公钥 $ openssl dsa -in dsakey0.pem -pubout -out dsakey0-pub.pem #生成rsa算法的公钥 $ openssl rsa -in rsakey0.pem -pubout -out rsakey0-pub.pem 3.自签名证书的生成方法 #产生DSA算法的证书 $ openssl req -x509 -key dsakey0.pem -days 365 -out mycert-dsa.pem -new #产生RSA算法的证书 $ openssl req -x509 -key rsakey0.pem -days 365 -out mycert-rsa.pem -new 4.使用证书进行邮件加密 我们的明文信件内容: $ cat test.txt 111111 222222 333333 444444 aaaaaa 使用证书对明文信件进行加密,输出到etest.txt文件: $ openssl smime -encrypt -in test.txt -out etest.txt mycert-rsa.pem 查看加密后的密文内容: $ cat etest.txt MIME-Version: 1.0 Content-Disposition: attachment; filename="smime.p7m" Content-Type: application/x-pkcs7-mime; smime-type=enveloped-data; name="smime.p7m" Content-Transfer-Encoding: base64 MIIBYAYJKoZIhvcNAQcDoIIBUTCCAU0CAQAxgewwgekCAQAwUjBFMQswCQYDVQQG EwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lk

openssl,CA证书生成命令集合

多级证书 平时我们自己签发CA证书再签发服务器证书的场景其实都非常简单。浏览器把自签CA导入后,就可以信任由这个CA直接签发的服务器证书。 但是实际上网站使用的证书肯定都不是由根CA直接签发的,比如 淘宝登陆服务器使用的证书。 我之前是自己写了脚本由自签CA直接签发服务器证书,为了真清楚的理解一下证书链的作用就直接使用openssl先签发2层的子CA,再由子CA去签发服务器证书。 手动签发证书的脚本如下: 生成自签CA # cat makerootca.sh #!/bin/bash DIR=/root/ssl.test2 mkdir -p $DIR/demoCA/{private,newcerts} touch $DIR/demoCA/index.txt echo 01 > $DIR/demoCA/serial opensslgenrsa -des3 -out $DIR/demoCA/private/cakey.pem 2048

opensslreq -new -x509 -days 3650 -key $DIR/demoCA/private/cakey.pem -out $DIR/demoCA/careq.pem 签发二级CA的脚本 https://www.wendangku.net/doc/1f9363347.html,f/root/ssl.test2 # cat no2domain.sh #!/bin/bash [ $# -ne 1 ] && echo "$0 NAME" && exit NAME=$1 DIR=/root/ssl.test2/autoget mkdir -p $DIR opensslgenrsa -des3 -out $DIR/$NAME.key 2048 openssl x509 -in $DIR/../demoCA/careq.pem -noout -text opensslrsa -in $DIR/$NAME.key -out $DIR/$NAME.key opensslreq -new -days 3650 -key $DIR/$NAME.key -out $DIR/$NAME.csr opensslca -extensions v3_ca -in $DIR/$NAME.csr -config $DIR/../https://www.wendangku.net/doc/1f9363347.html,f -days 3000 -out $DIR/$NAME.crt -cert $DIR/../demoCA/careq.pem -keyfile $DIR/../demoCA/private/cakey.pem 签发三级CA的脚本 # cat no3domain.sh #!/bin/bash #[ $# -ne 1 ] && echo "$0 NAME" && exit NAME=calv3 DIR=/root/ssl.test2/autoget opensslgenrsa -des3 -out $DIR/$NAME.key 2048

用Keytool和OpenSSL生成和签发数字证书

4.2.1 建立工作目录 demoCA 4.2.2 生成CA私钥以及自签名根证书 4.2.2.1 生成CA私钥 openssl genrsa -out demoCA\ca-key.pem 1024 4.2.2.2 生成待签名证书 openssl req -new -out demoCA\ca-req.csr -key demoCA\ca-key.pem 4.2.2.3 用CA私钥进行自签名 openssl x509 -req -in demoCA\ca-req.csr -out ca\ca-cert.pem -signkey demoCA\ca-key.pem -days 365 4.3 设置Tomcat 4.x 在本文中用符号"%JDK_HOME%"来表示JDK的安装位置,用符号"%TCAT_HOME%" 表示Tomcat的安装位置。 4.3.1建立工作目录 mkdir server 4.3.2 生成server端证书 4.3.2.1 生成KeyPair %JDK_HOME%\bin\keytool -genkey -alias tomcat_server -validity 365 -keyalg RSA -keysize 1024 -keypass 123456 -storepass 123456 -keystore server\server_keystore 4.3.2.2 生成待签名证书 %JDK_HOME%\bin\keytool -certreq -alias tomcat_server -sigalg MD5withRSA -file server\server.csr -keypass 123456 -keystore server\server_keystore -storepass changeit 4.3.2.3 用CA私钥进行签名

使用OPENSSL编写服务器和客户端代码实例

使用OPENSSL编写服务器和客户端代码实例使用相同的ca生成两个证书,一个是server.cer,一个是client.cer,注意生成server.cer的时候必须指明证书可以用于服务端的。 服务器代码: 1.#include "openssl/bio.h" 2.#include "openssl/ssl.h" 3.#include "openssl/err.h" 4. 5.#include 6. 7.#define EXIT_IF_TRUE(x) if (x) \ 8. do { \ 9. fprintf(stderr, "Check '%s' is true\n", #x); \ 10. ERR_print_errors_fp(stderr); \ 11. exit(2); \ 12. }while(0) 13. 14.int main(int argc, char **argv) 15.{ 16. SSL_CTX *ctx; 17. SSL *ssl; 18. X509 *client_cert; 19. 20. char szBuffer[1024]; 21. int nLen; 22. 23. struct sockaddr_in addr; 24. int len; 25. int nListenFd, nAcceptFd; 26. 27.// 初始化 28. cutil_init(); 29. cutil_log_set_level(LOG_ALL); 30. cutil_log_set_stderr(1);

31. SSLeay_add_ssl_algorithms(); 32. OpenSSL_add_all_algorithms(); 33. SSL_load_error_strings(); 34. ERR_load_BIO_strings(); 35. 36.// 我们使用SSL V3,V2 37. EXIT_IF_TRUE((ctx = SSL_CTX_new (SSLv23_method())) == NULL); 38. 39.// 要求校验对方证书 40. SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); 41. 42.// 加载CA的证书 43. EXIT_IF_TRUE (!SSL_CTX_load_verify_locations(ctx, "cacert.cer", NULL)); 44. 45.// 加载自己的证书 46. EXIT_IF_TRUE (SSL_CTX_use_certificate_file(ctx, "server.cer", SSL_FILETYPE_PEM ) <= 0) ; 47. 48.// 加载自己的私钥 49. EXIT_IF_TRUE (SSL_CTX_use_PrivateKey_file(ctx, "server.key", SSL_FILETYPE_PEM) <= 0) ; 50. 51.// 判定私钥是否正确 52. EXIT_IF_TRUE (!SSL_CTX_check_private_key(ctx)); 53. 54.// 创建并等待连接 55. nListenFd = cutil_socket_new(SOCK_STREAM); 56. cutil_socket_bind(nListenFd, NULL, 8812, 1); 57. 58. memset(&addr, 0, sizeof(addr)); 59. len = sizeof(addr); 60. nAcceptFd = accept(nListenFd, (struct sockaddr *)&addr, (size_t *)&len); 61. cutil_log_debug("Accept a connect from [%s:%d]\n", 62. inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); 63. 64.// 将连接付给SSL 65. EXIT_IF_TRUE( (ssl = SSL_new (ctx)) == NULL); 66. SSL_set_fd (ssl, nAcceptFd); 67. EXIT_IF_TRUE( SSL_accept (ssl) != 1); 68. 69.// 进行操作 70. memset(szBuffer, 0, sizeof(szBuffer)); 71. nLen = SSL_read(ssl,szBuffer, sizeof(szBuffer)); 72. fprintf(stderr, "Get Len %d %s ok\n", nLen, szBuffer);

相关文档