实验环境:openssl 1.1.1k

EVP_CipherInit_ex()、EVP_CipherUpdate() 和 EVP_CipherFinal_ex() 是可用于解密或加密的函数。执行的操作取决于enc参数的值。加密时应设置为 1,解密时设置为 0,保持值不变为 -1。

// 创建密码上下文
EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void);
// 清除密码上下文中的所有信息并释放与其关联的任何已分配内存,包括ctx本身。
// 应在使用密码的所有操作完成后调用此函数,以便敏感信息不会保留在内存中。
void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
/**
函数作用:初始化密码上下文ctx
ctx  : 由 EVP_CIPHER_CTX_new() 创建
type : 使用的算法类型,例如:EVP_aes_256_cbc()、EVP_aes_128_cbc()
impl :密码类型,如果impl为 NULL,则使用默认实现。一般都设置为NULL
key  : 加密密钥
iv   : 偏移量
enc  : 1 - 加密;0 - 解密
**/
int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,ENGINE *impl, const unsigned char *key, const unsigned char *iv, int enc);
/**
输入 in 缓冲区中的 inl 字节的数据并将加/解密数据写入 out。可以多次调用此函数来加/解密连续的数据块。
**/
int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,int *outl, const unsigned char *in, int inl);
/**
输出 缓冲区中剩余的数据。必须在 EVP_CipherUpdate() 之后调用。
outm : 为输出缓冲区中剩余部分
**/
int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
/**
启用或禁用填充。在使用 EVP_EncryptInit_ex()、EVP_DecryptInit_ex() 或 EVP_CipherInit_ex() 为加密或解密设置上下文后,应调用此函数。
默认情况下,加密操作使用标准块填充进行填充,并且在解密时检查并删除填充。
如果填充参数 padding 设置为零,则不执行填充,此时加密或解密的数据总量必须是块大小的倍数,否则将发生错误。默认情况下填充是启用的。padding 为0 则禁用填充,否则启用填充
**/
int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *x, int padding);
/**
这是一个示例代码
**/unsigned char key[] = "0123456789abcdeF";
unsigned char iv[] = "1234567887654321";/**
inBuf : 输入数据
inl   : 输入数据长度
out   : 输出缓冲区,由调用者确定其大小
outl  : 输出数据的长度
cipher:算法类型。例如:EVP_aes_128_cbc()、EVP_aes_256_cbc()
**/
int do_crypt(const char *inBuf, int inl, char *out, int *outl, const EVP_CIPHER *cipher, int enc)
{if(NULL == inBuf || NULL == out){return -1;}int templ, total;// 创建上下文EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();// 初始化.设置算法类型和加解密类型以及加密密钥和偏移量EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc);// 设置是否启用填充.默认是启用的// 如果填充参数为零,则不执行填充,此时加密或解密的数据总量必须是块大小的倍数,否则将发生错误。EVP_CIPHER_CTX_set_padding(ctx, 1);
#if 0// key 和 iv 长度断言检查。断言长度随着 cipher 的不同而不同OPENSSL_assert(EVP_CIPHER_CTX_key_length(ctx) == 16);OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) == 16);
#endiftempl= 0;total = 0;if (!EVP_CipherUpdate(ctx, out, &templ, inBuf, inl)){printf("EVP_CipherUpdate fail...");goto err;}total += templ;if (!EVP_CipherFinal_ex(ctx, out + total, &templ)){printf("EVP_CipherFinal_ex fail...");goto err;}total += templ;*outl = total;EVP_CIPHER_CTX_free(ctx);return 0;
err:EVP_CIPHER_CTX_free(ctx);return -1;
}

EVP_CipherInit_ex 中可支持的算法类型(详细请见 openssl/evp.h 头文件)

const EVP_CIPHER *EVP_aes_128_ecb(void);
const EVP_CIPHER *EVP_aes_128_cbc(void);
const EVP_CIPHER *EVP_aes_128_cfb1(void);
const EVP_CIPHER *EVP_aes_128_cfb8(void);
const EVP_CIPHER *EVP_aes_128_cfb128(void);const EVP_CIPHER *EVP_aes_128_ofb(void);
const EVP_CIPHER *EVP_aes_128_ctr(void);
const EVP_CIPHER *EVP_aes_128_ccm(void);
const EVP_CIPHER *EVP_aes_128_gcm(void);
const EVP_CIPHER *EVP_aes_128_xts(void);
const EVP_CIPHER *EVP_aes_128_wrap(void);
const EVP_CIPHER *EVP_aes_128_wrap_pad(void);const EVP_CIPHER *EVP_aes_128_ocb(void);const EVP_CIPHER *EVP_aes_192_ecb(void);
const EVP_CIPHER *EVP_aes_192_cbc(void);
const EVP_CIPHER *EVP_aes_192_cfb1(void);
const EVP_CIPHER *EVP_aes_192_cfb8(void);
const EVP_CIPHER *EVP_aes_192_cfb128(void);const EVP_CIPHER *EVP_aes_192_ofb(void);
const EVP_CIPHER *EVP_aes_192_ctr(void);
const EVP_CIPHER *EVP_aes_192_ccm(void);
const EVP_CIPHER *EVP_aes_192_gcm(void);
const EVP_CIPHER *EVP_aes_192_wrap(void);
const EVP_CIPHER *EVP_aes_192_wrap_pad(void);const EVP_CIPHER *EVP_aes_192_ocb(void);const EVP_CIPHER *EVP_aes_256_ecb(void);
const EVP_CIPHER *EVP_aes_256_cbc(void);
const EVP_CIPHER *EVP_aes_256_cfb1(void);
const EVP_CIPHER *EVP_aes_256_cfb8(void);
const EVP_CIPHER *EVP_aes_256_cfb128(void);const EVP_CIPHER *EVP_aes_256_ofb(void);
const EVP_CIPHER *EVP_aes_256_ctr(void);
const EVP_CIPHER *EVP_aes_256_ccm(void);
const EVP_CIPHER *EVP_aes_256_gcm(void);
const EVP_CIPHER *EVP_aes_256_xts(void);
const EVP_CIPHER *EVP_aes_256_wrap(void);
const EVP_CIPHER *EVP_aes_256_wrap_pad(void);const EVP_CIPHER *EVP_aes_256_ocb(void);const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void);
const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void);
const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void);
const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void);const EVP_CIPHER *EVP_aria_128_ecb(void);
const EVP_CIPHER *EVP_aria_128_cbc(void);
const EVP_CIPHER *EVP_aria_128_cfb1(void);
const EVP_CIPHER *EVP_aria_128_cfb8(void);
const EVP_CIPHER *EVP_aria_128_cfb128(void);const EVP_CIPHER *EVP_aria_128_ctr(void);
const EVP_CIPHER *EVP_aria_128_ofb(void);
const EVP_CIPHER *EVP_aria_128_gcm(void);
const EVP_CIPHER *EVP_aria_128_ccm(void);
const EVP_CIPHER *EVP_aria_192_ecb(void);
const EVP_CIPHER *EVP_aria_192_cbc(void);
const EVP_CIPHER *EVP_aria_192_cfb1(void);
const EVP_CIPHER *EVP_aria_192_cfb8(void);
const EVP_CIPHER *EVP_aria_192_cfb128(void);const EVP_CIPHER *EVP_aria_192_ctr(void);
const EVP_CIPHER *EVP_aria_192_ofb(void);
const EVP_CIPHER *EVP_aria_192_gcm(void);
const EVP_CIPHER *EVP_aria_192_ccm(void);
const EVP_CIPHER *EVP_aria_256_ecb(void);
const EVP_CIPHER *EVP_aria_256_cbc(void);
const EVP_CIPHER *EVP_aria_256_cfb1(void);
const EVP_CIPHER *EVP_aria_256_cfb8(void);
const EVP_CIPHER *EVP_aria_256_cfb128(void);const EVP_CIPHER *EVP_aria_256_ctr(void);
const EVP_CIPHER *EVP_aria_256_ofb(void);
const EVP_CIPHER *EVP_aria_256_gcm(void);
const EVP_CIPHER *EVP_aria_256_ccm(void);

EVP_Encryp 和 EVP_Decryp 系列:

/**
设置密码上下文ctx以使用来自 ENGINE impl 的密码类型进行加密。ctx必须在调用此函数之前创建。类型通常由诸如 EVP_aes_256_cbc() 之类的函数提供。如果impl为 NULL,则使用默认实现。key是要使用的对称密钥,iv是要使用的 IV(如有必要),用于密钥和 IV 的实际字节数取决于密码。可以在初始调用中将除type之外的所有参数设置为 NULL ,并在后续调用中提供其余参数.
**/
int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,ENGINE *impl, const unsigned char *key, const unsigned char *iv);
/**
加密inl缓冲区中的inl字节in并将加密版本写入out。可以多次调用此函数来加密连续的数据块。
写入的数据量取决于加密数据的块对齐。对于大多数密码和模式,写入的数据量可以是从零字节到 (inl + cipher_block_size - 1) 字节的任何内容。对于包装密码模式,写入的数据量可以是从零字节到 (inl + cipher_block_size) 字节的任何内容。
对于流密码,写入的数据量可以是从零字节到 inl 字节的任何内容。因此,out应该为正在执行的操作包含足够的空间。实际写入的字节数放在outl中
**/
int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,int *outl, const unsigned char *in, int inl);
/**
必须在 EVP_EncryptUpdate 之后调用,用来加密原文剩余部分。
**/
int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);

EVP_DecryptInit_ex()、EVP_DecryptUpdate()和EVP_DecryptFinal_ex()是对应的解密操作。如果启用了填充并且最终块的格式不正确,则 EVP_DecryptFinal() 将返回错误代码。

使用 IDEA 加密字符串:

int do_crypt(char *outfile){unsigned char outbuf[1024];int outlen, tmplen;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;ctx = EVP_CIPHER_CTX_new();EVP_EncryptInit_ex(ctx, EVP_idea_cbc(), NULL, key, iv);if (!EVP_EncryptUpdate(ctx, outbuf, &outlen, intext, strlen(intext))) {EVP_CIPHER_CTX_free(ctx);return -1;}if (!EVP_EncryptFinal_ex(ctx, outbuf + outlen, &tmplen)) {EVP_CIPHER_CTX_free(ctx);return -1;}outlen += tmplen;EVP_CIPHER_CTX_free(ctx);out = fopen(outfile, "wb");if (out == NULL) {return -1;}fwrite(outbuf, 1, outlen, out);fclose(out);return 0;}

Openssl 对称加解密函数 - EVP_Cipher、EVP_Encrypt、EVP_Decryp 系列相关推荐

  1. [crypto]-02-非对称加解密RSA原理概念详解

    说明:本文使用的数据来自网络,重复的太多了,也不知道哪篇是原创. 算法原理介绍 step 说明 描述 备注 1 找出质数 P .Q - 2 计算公共模数 N = P * Q - 3 欧拉函数 φ(N) ...

  2. Openssl Aes加解密使用示例

    Openssl Aes加解密使用示例 Aes简介 设置Aes密钥 Aes算法CBC加解密 Aes简介 Aes是分组加密算法,主要基于块加密,选取固定长度的密钥去加密明文中固定长度的块,生成的密文块与明 ...

  3. python openssl 证书加解密过程感觉是这样

    python openssl 证书加解密过程感觉是这样 第一步 生成2048 bit的PEM格式的RSA Key:Key.pem openssl genrsa -out Key.pem -f4 204 ...

  4. linux证书存放路径,利用Tar和OpenSSL轻松加/解密文件和目录

    众所周知要想保护数据的安全比较简单快捷的方法无疑是给文件和目录进行加密的操作.相比于Windows给文件和目录进行加/解密的操作,在Linux上进行加/解密文件和目录要复杂一点.那么我们到底有没有什么 ...

  5. linux c openssl aes 加解密

    1.OpenSSL提供了AES加解密算法的API const char *AES_options(void); AES算法状态,是所有支持或者是部分支持. 返回值:"aes(full)&qu ...

  6. openssl enc 加解密

    介绍 enc - 对称加密例程,使用对称密钥对数据进行加解密,特点是速度快,能对大量数据进行处理.算法有流算法和分组加密算法,流算法是逐字节加密,数据经典算法,但由于其容易被破译,现在已很少使用:分组 ...

  7. openssl 3des 加解密

    一. 3DES加密原理 3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称.它相当于是对每个数据块应用三 ...

  8. 某付宝APP之某加油小程序对称加解密算法解析

    前言 前几天发了一个某付宝小程序的sign参数md5加密拿到明文参数的帖子- 又发现一个别的小程序,好像是用的对称加密,耐不住好奇心,就试了试-结果成功实现了加解密的操作.遂发帖记录一下. 工具 fi ...

  9. openssl aes加解密的使用

    1.先写一个用于生产二进制文件的工具 使用说明:新建main.c,将代码拷贝到main.c中,在linux环境下执行gcc main.c -o x,输出可执行文件x #include <stdi ...

最新文章

  1. CentOS-6.4-x86_64 下安装mysql5.6
  2. QWT中Qdial的入门介绍
  3. python socket发送数组_利用pyprocessing初步探索数组排序算法可视化
  4. 编译原理实验语义分析_「编译原理」LL(1)文法分析,简单优先分析
  5. Jquery 全选,反选
  6. 概述造船业ERP信息化的方法
  7. php扩展拦截请求,PHP的拦截器实例分析
  8. 小白该如何学习Linux操作系统(1)
  9. 回忆我的网络生活(一)
  10. Lucene知识小总结8:索引查询
  11. 由一本书看一个行业 -- 网上购书之比较
  12. oracle性质是渐进正态性,基于惩罚函数的回归量变选择方法.doc
  13. 数字系统设计中形式验证
  14. IR2110不具备隔离驱动作用
  15. JAVA 模拟扑克牌洗牌发牌案例
  16. HTML5Point 如何去版权图片?
  17. dell服务器驱动安装安装系统安装,dellR720服务器安装系统win server2012X64方法
  18. c语言编程*三角形图形右看齐,EOJ 3213 向右看齐
  19. 24Python读取PPT文档内容
  20. 大数据的数据库设计原则有哪些

热门文章

  1. JavaScript之作用域链 1
  2. direct wifi 投屏_direct wifi 投屏_告别Wifi直接投AOC无线投屏显示器轻松用
  3. Si9000计算嘉立创JLC04161H-7628(推荐/免费)方法
  4. matlab读取txt到矩阵,如何在MATLAB中将文本文件中的数据读入矩阵(How to read data from a text file into a matrix in MATLAB)...
  5. QBasic语言程序设计 金怀群 pdf
  6. 可调电位器/滑动变阻器拆解
  7. java 银行叫号系统
  8. UG NX 12 基准平面
  9. java 资源映射访问本地磁盘的文件或者访问项目静态资源
  10. Aspose.PDF for Java系列5-转化PDF文档为Word