linux openssl 值 AES加解密解说,本文章只要对openssl 之 EVP的api 函数讲解和代码例程展示。
openssl EVP相关api函数定义在(openssl/aes.h)头文件间,摘取如下所以:
/********对称加解密常用并推荐使用的api函数********/
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);
/********与上面的api函数功能功能相似,确切说上述函数都是调用下方函数进一步封装的********/
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);
/********下列函数为openssl旧版本所支持,为兼容以前的代码而被保留下来********/
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);
/* 其他常用api函数*/
int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad);
EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void);
void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx);
int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
上面所列出的函数虽然很多,但是大部分是功能重复的,有的是旧的版本支持的函数,新的版本中已经可以不再使用了。事实上,函数EVP_EncryptInit, EVP_EncryptFinal, EVP_DecryptInit,EVP_DecryptFinal, 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结构的内存的情况下重用该结构,方便很多。下面我们分别对这些函数进行介绍。
函数解说:
1.int EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a)
该函数初始化一个EVP_CIPHER_CTX结构体变量,只有初始化后该结构体才能在下面介绍的函数中使用。操作成功返回1,否则返回0。
注意openssl1.1.1开始不能使用“ EVP_CIPHER_CTX 变量名”来声明,否则编程出错。需要使用api函数:EVP_CIPHER_CTX_new来申请EVP_CIPHER_CTX 结构体变量内存。不适用是记得使用api函数:EVP_CIPHER_CTX_free释放内存,例如一下所示:
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); //申请内存块,成功返回非NULL,失败返回NULL
........
EVP_CIPHER_CTX_free(ctx); //释放内存块
/*
function:EVP_EncryptInit_ex
parameter:
ctx: 必须已初始化的EVP_CIPHER_CTX结构体参数
type:通常通过函数类型来提供参数,如EVP_aes_128_ecb()函数的形式
impl:通常使用NULL,即使用缺省的实现算法
key: 用于加密的对称密钥
iv: iv参数是初始化向量(如果需要的话),不需要则设置为NULL
return:成功1, 失败0
*/
2.int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, unsigned char *key, unsigned char *iv);
若使用EVP_EncryptUpdate和EVP_EncryptFinal_ex进行加密的话,需要先调用EVP_EncryptInit_ex函数后才能进行加密操作。
/*
function:EVP_EncryptUpdate
parameter:
ctx: 必须已初始化的EVP_CIPHER_CTX结构体参数
out: 加密后的数据内存块首地址
outl: 加密后的数据字节长度
in: 需要加密的原文数据内存块首地址
inl: 需要加密的原文数据字节长度
return:成功1, 失败0
*/
3.int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,int *outl, unsigned char *in, int inl);
该函数用于对原文数据进行加密操作,加密数据范围,即参数outl的范围等于参数inl - inl%cipher_block_size。若需要加密的数据长度不是cipher_block_size整数倍,又没有disable padding功能,则剩余还没有加密的数据需要调用函数EVP_EncryptFinal_ex来处理。若需要加密的数据长度为cipher_block_size的整数倍,又disable padding功能,则参数outl == inl。若需要加密的数据长度为cipher_block_size的整数倍,但是没有disable padding功能,还是需要调用函数EVP_EncryptFinal_ex来结束加密操作。