openssl evp 对称加密(AES_ecb,ccb)

evp.h 封装了openssl常用密码学工具,以下主要说对称加密的接口

1. 如下使用 aes_256_ecb 模式的加密解密测试代码

    unsigned char key[] = {};
unsigned char iv[] = {};
unsigned char *inStr = "this is test string";
int inLen = strlen(inStr);
int encLen = ;
int outlen = ;
unsigned char encData[]; printf("source: %s\n",inStr); //加密
EVP_CIPHER_CTX *ctx;
ctx = EVP_CIPHER_CTX_new(); EVP_CipherInit_ex(ctx, EVP_aes_256_ecb(), NULL, key, iv, );
EVP_CipherUpdate(ctx, encData, &outlen, inStr, inLen);
encLen = outlen;
EVP_CipherFinal(ctx, encData+outlen, &outlen);
encLen += outlen;
EVP_CIPHER_CTX_free(ctx); //解密
int decLen = ;
outlen = ;
unsigned char decData[];
EVP_CIPHER_CTX *ctx2;
ctx2 = EVP_CIPHER_CTX_new();
EVP_CipherInit_ex(ctx2, EVP_aes_256_ecb(), NULL, key, iv, );
EVP_CipherUpdate(ctx2, decData, &outlen, encData, encLen);
decLen = outlen;
EVP_CipherFinal(ctx2, decData+outlen, &outlen);
decLen += outlen;
EVP_CIPHER_CTX_free(ctx2); decData[decLen] = '\0';
printf("decrypt: %s\n",decData);

如上这种init,update,final的调用方式和之前 提供的哈希接口调用方式差不多

大致流程

EVP_CipherInit_ex 初始化加密使用的key,iv,算法模式,最后 一个参数,1表示加密,0表示解密

EVP_CipherUpdate 加密解密处理

EVP_CipherFinal 获取结果

2.  由上测试代码中 EVP_CipherInit_ex(ctx, EVP_aes_256_ecb(), NULL, key, iv, 1); 使用的算法模式为  EVP_aes_256_ecb()

根据接口 evp.h可知其他的对称加密算法有如下

const EVP_CIPHER *EVP_des_ecb(void);
const EVP_CIPHER *EVP_des_ede(void);
const EVP_CIPHER *EVP_des_ede3(void);
...
const EVP_CIPHER *EVP_idea_ecb(void);
const EVP_CIPHER *EVP_idea_cfb64(void);
const EVP_CIPHER *EVP_idea_ofb(void);
.....
const EVP_CIPHER *EVP_bf_cbc(void);
const EVP_CIPHER *EVP_bf_cfb64(void);
.....
const EVP_CIPHER *EVP_cast5_ecb(void);
const EVP_CIPHER *EVP_cast5_cbc(void);
.....
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_256_ecb(void);
const EVP_CIPHER *EVP_aes_256_cbc(void);
const EVP_CIPHER *EVP_aes_256_cfb1(void);
....
const EVP_CIPHER *EVP_camellia_128_cfb1(void);
const EVP_CIPHER *EVP_camellia_128_cfb8(void);
const EVP_CIPHER *EVP_camellia_128_cfb128(void);
...... //以上省略表示还有很多,这里只是列出部分

选取相应的算法对应修改上面的测试代码即可,实现对称加密体系中其他算法的加密解密

3. EVP中对称加密的主要接口有

__owur int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
const unsigned char *key, const unsigned char *iv);
/*__owur*/ int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,
const EVP_CIPHER *cipher, ENGINE *impl,
const unsigned char *key,
const unsigned char *iv);
/*__owur*/ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
int *outl, const unsigned char *in, int inl);
/*__owur*/ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out,
int *outl);
/*__owur*/ int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out,
int *outl); __owur int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
const unsigned char *key, const unsigned char *iv);
/*__owur*/ int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx,
const EVP_CIPHER *cipher, ENGINE *impl,
const unsigned char *key,
const unsigned char *iv);
/*__owur*/ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
int *outl, const unsigned char *in, int inl);
__owur int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm,
int *outl);
/*__owur*/ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm,
int *outl); __owur int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
const unsigned char *key, const unsigned char *iv,
int enc);
/*__owur*/ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx,
const EVP_CIPHER *cipher, ENGINE *impl,
const unsigned char *key,
const unsigned char *iv, int enc);
__owur int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
int *outl, const unsigned char *in, int inl);
__owur int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm,
int *outl);
__owur int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm,
int *outl);

4. 上面的例子之中,我使用的是EVP_Cipher相关api处理的对称加密

如下,我们还可以直接使用上面的 EVP_Encrypt,EVP_Decrypt 接口来处理加密解密

封装加密解密

//加密
int kk_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
unsigned char *iv, unsigned char *ciphertext)
{
EVP_CIPHER_CTX *ctx; int len; int ciphertext_len;
ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);
EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len);
ciphertext_len = len;
EVP_EncryptFinal_ex(ctx, ciphertext + len, &len);
ciphertext_len += len;
EVP_CIPHER_CTX_free(ctx); return ciphertext_len;
} //解密
int kk_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
unsigned char *iv, unsigned char *plaintext)
{
EVP_CIPHER_CTX *ctx; int len;
int plaintext_len; ctx = EVP_CIPHER_CTX_new(); EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);
EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len);
plaintext_len = len; EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
plaintext_len += len; EVP_CIPHER_CTX_free(ctx); return plaintext_len;
}

调用测试:

    unsigned char key[] = {};
unsigned char iv[] = {};
unsigned char *plaintext = (unsigned char *)"This is Test Plain Data,This is Test Plain Data.";
unsigned char ciphertext[];
unsigned char decryptedtext[];
int decryptedtext_len, ciphertext_len;
printf("source is: \n%s\n",plaintext); //加密
ciphertext_len = kk_encrypt (plaintext, strlen ((char *)plaintext), key, iv,
ciphertext); //解密
decryptedtext_len = kk_decrypt(ciphertext, ciphertext_len, key, iv,
decryptedtext); decryptedtext[decryptedtext_len] = '\0'; printf("Decrypted text is:\n");
printf("%s\n", decryptedtext);

和上面第一个例子的流程差不多,修改其中的对称体系使用的算法即可实现其他算法处理

5. 如果不使用EVP提供的接口,当然还可以直接使用 aes.h 提供的接口

主要接口有

/* This should be a hidden type, but EVP requires that the size be known */
struct aes_key_st {
# ifdef AES_LONG
unsigned long rd_key[ * (AES_MAXNR + )];
# else
unsigned int rd_key[ * (AES_MAXNR + )];
# endif
int rounds;
};
typedef struct aes_key_st AES_KEY; const char *AES_options(void); int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key); void AES_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void AES_decrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key); void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key, const int enc);
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, const int enc);
void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, int *num, const int enc);
void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, int *num, const int enc);
void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, int *num, const int enc);
void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, int *num);
/* NB: the IV is _two_ blocks long */
void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, const int enc);
/* NB: the IV is _four_ blocks long */
void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
const AES_KEY *key2, const unsigned char *ivec,
const int enc); int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
unsigned char *out,
const unsigned char *in, unsigned int inlen);
int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
unsigned char *out,
const unsigned char *in, unsigned int inlen);

测试接口AES_encrypt,AES_decrypt

//测试1
void kk_aes_encrypt(char *inData,char *key,char *outData)
{
AES_KEY encKey;
AES_set_encrypt_key(key, , &encKey); int inLen = strlen(inData);
int encLen = ;
//分组加密
while (encLen <inLen) {
AES_encrypt(inData, outData, &encKey);
inData += AES_BLOCK_SIZE;
outData+=AES_BLOCK_SIZE;
encLen +=AES_BLOCK_SIZE;
} } void kk_aes_decrypt(char *inData,char *key,char *outData)
{
AES_KEY decKey;
AES_set_decrypt_key(key, , &decKey);
int inLen = strlen(inData);
int decLen = ;
//分组处理
while (decLen < inLen) {
AES_decrypt(inData, outData, &decKey);
inData += AES_BLOCK_SIZE;
outData+=AES_BLOCK_SIZE;
decLen +=AES_BLOCK_SIZE;
}
} //测试
void testSIMPLEAES()
{
char *key = "this key";
char *ins = "test str dat,test str dat,test str dat,test str dat,QQQS";
printf("src:%s\n",ins);
char *encDT = malloc(strlen(ins));
kk_aes_encrypt(ins, key, encDT); char *decDT = malloc(strlen(encDT));
kk_aes_decrypt(encDT, key, decDT);
printf("dec:%s\n",decDT);
}

测试AES_cbc_encrypt接口

    AES_KEY encKEy;
unsigned char *uk = "uk123";
char encIV[AES_BLOCK_SIZE] = {};
AES_set_encrypt_key(uk, , &encKEy);
char *inStr = "This wiki is intended as a place for collecting, organizing, and refining useful information about OpenSSL that is currently strewn among multiple locations and formats.";
char *encData = malloc();
AES_cbc_encrypt(inStr, encData, strlen(inStr), &encKEy, encIV, AES_ENCRYPT);
printf("src:%s\n",inStr); AES_KEY decKey;
AES_set_decrypt_key(uk, , &decKey);
char decIV[AES_BLOCK_SIZE] = {};
char *decData = malloc();
AES_cbc_encrypt(encData,decData, strlen(encData), &decKey, decIV, AES_DECRYPT);
decData[strlen(inStr)] = '\0';
printf("dec:%s\n",decData); if (strcmp(inStr, decData)==) {
printf("PASS\n");
}

总结:EVP 提供的两套对称加密的接口和上篇文章提到的哈希接口调用流程上很相似;

功能非常完善。

参考:https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption

测试使用openssl 1.1.0c

openssl evp 对称加密(AES_ecb,ccb)的更多相关文章

  1. openssl evp RSA 加密解密

    openssl evp RSA 加密解密 可以直接使用RSA.h 提供的接口 如下测试使用EVP提供的RSA接口 1. EVP提供的RSA 加密解密 主要接口: int EVP_PKEY_encryp ...

  2. openssl enc(对称加密)

    openssl系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html 对称加密工具.了解对称加密的原理后就很简单了,原理部分见下文. openss ...

  3. (9) openssl enc(对称加密)

    对称加密工具,了解对称加密的原理后就很简单了,原理部分见下文. openssl   enc  -ciphername   [-in filename]   [-out filename]   [-pa ...

  4. openssl 下的对称加密和非对称加密

    对称加密: 在加密和解密过程中使用相同的密钥, 或是两个可以简单地相互推算的密钥的加密算法. 非对称加密: 也称为公开加密, 它需要一个密钥对, 一个是公钥, 一个是私钥, 一个负责加密, 一个负责解 ...

  5. openssl之aes对称加密

    AES:密码学中的高级加密标准(Advanced Encryption Standard,AES),又称 Rijndael加密法. 对称加密:用同一个密码  加密/解密  文件. 使用openssl中 ...

  6. PHP的OpenSSL加密扩展学习(一):对称加密

    我们已经学过不少 PHP 中加密扩展相关的内容了.而今天开始,我们要学习的则是重点中的重点,那就是 OpenSSL 加密扩展的使用.为什么说它是重点中的重点呢?一是 OpenSSL 是目前 PHP 甚 ...

  7. openssl之aes加密(源码分析 AES_encrypt 与 AES_cbc_encrypt ,加密模式)

    首先要了解AES加密是什么,以及几种加密模式的区别.之后才是编程.具体的编程案例,在下面的链接. openssl之aes加密(AES_cbc_encrypt 与 AES_encrypt 的编程案例) ...

  8. iOS CommonCrypto 对称加密 AES ecb,cbc

    CommonCrypto 为苹果提供的系统加密接口,支持iOS 和 mac 开发: 不仅限于AES加密,提供的接口还支持其他DES,3DES,RC4,BLOWFISH等算法, 本文章主要讨论AES在i ...

  9. [Node.js] 对称加密、公钥加密和RSA

    原文地址:http://www.moye.me/2015/06/14/cryptography_rsa/ 引子 对于加解密,我一直处于一种知其然不知其所以然的状态,项目核心部分并不倚重加解密算法时,可 ...

随机推荐

  1. Android开发新手学习总结(六)——android开发目录结构【图文版】

    转载链接:http://bbs.itcast.cn/thread-87059-1-1.html?rss 既然已经搭建好环境了,那就对Android Studio中项目目录结构做个简单的了解了,这里以最 ...

  2. cocos2dx打包apk

    一.相关工具准备 1.SDK 2.NDK 3.ANT 4.JDK 并且搭建好JDK环境 二.搭建环境 1.打开cocos2dx目录下的setup.py文件 2.如图所示,按照提示分别输入之前下载的ND ...

  3. python利用redis构成一个队列

    例子在 http://peter-hoffmann.com/2012/python-simple-queue-redis-queue.html 英文 http://www.django-china.c ...

  4. python与ruby的差别

    1.引用文件差别 Ruby:同一目录下的文件,如/usr/local/ruby/foo.rb与/usr/local/ruby/bar.rb两个文件.如果直接在foo.rb中 require 'bar' ...

  5. Nginx:轻量级高性能的Web服务器

    Nginx ("engine x") 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器.Nginx是由Igor Sysoev为俄罗斯访问量第二的R ...

  6. asp.net页面生命周期请求管道19个事件

    HttpContext: ecb→ HttpWorkerRequest→HttpContext HttpApplicationFactory.获取了HttpApplication实例之后. (1)Be ...

  7. Java设计模式(三)——观察者模式和监听器

    为了实现多个模块之间的联动,最好的方法是使用观察者模式.网上介绍的资料也比较多,今天我就从另一个方面谈谈自己对观察者模式的理解.从JDK提供的支持库里,我们能够找到四个对象:Observable.Ob ...

  8. Thinkphp回顾之(四)查询方法深入学习

    本次讲的查询方法主要有:表达式查询,模糊查询,between语句,in语句,区间查询,统计数据,普通方式查询,但大多数都只是引入数组而已,明白了第一个,其他的也就差不多全明白了,唯一要注意的是在后台中 ...

  9. webapi mvc session一直获取不到问题

    前一段时间在给移动端写接口时遇到一个调用接口发送邮箱 session 一直获取不到的问题.我来给遇到问题的同志们说一说 自个在网上查了好多资料,问了一些朋友后.终于找到解决方案了. 大家都知道weba ...

  10. [LeetCode_5] Longest Palindromic Substring

    LeetCode: 5. Longest Palindromic Substring class Solution { public: //动态规划算法 string longestPalindrom ...