博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
openssl evp 对称加密(AES_ecb,ccb)
阅读量:6247 次
发布时间:2019-06-22

本文共 10444 字,大约阅读时间需要 34 分钟。

openssl evp 对称加密(AES_ecb,ccb)

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

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

unsigned char key[32] = {
1}; unsigned char iv[16] = {
0}; unsigned char *inStr = "this is test string"; int inLen = strlen(inStr); int encLen = 0; int outlen = 0; unsigned char encData[1024]; 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, 1); EVP_CipherUpdate(ctx, encData, &outlen, inStr, inLen); encLen = outlen; EVP_CipherFinal(ctx, encData+outlen, &outlen); encLen += outlen; EVP_CIPHER_CTX_free(ctx); //解密 int decLen = 0; outlen = 0; unsigned char decData[1024]; EVP_CIPHER_CTX *ctx2; ctx2 = EVP_CIPHER_CTX_new(); EVP_CipherInit_ex(ctx2, EVP_aes_256_ecb(), NULL, key, iv, 0); 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[32] = {
8}; unsigned char iv[16] = {
6}; unsigned char *plaintext = (unsigned char *)"This is Test Plain Data,This is Test Plain Data."; unsigned char ciphertext[128]; unsigned char decryptedtext[128]; 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[4 * (AES_MAXNR + 1)];# else    unsigned int rd_key[4 * (AES_MAXNR + 1)];# 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

//测试1void kk_aes_encrypt(char *inData,char *key,char *outData){    AES_KEY encKey;    AES_set_encrypt_key(key, 128, &encKey);        int inLen = strlen(inData);    int encLen = 0;    //分组加密    while (encLen 

测试AES_cbc_encrypt接口

AES_KEY encKEy;    unsigned char *uk = "uk123";    char encIV[AES_BLOCK_SIZE] = {
0}; AES_set_encrypt_key(uk, 128, &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(1024); AES_cbc_encrypt(inStr, encData, strlen(inStr), &encKEy, encIV, AES_ENCRYPT); printf("src:%s\n",inStr); AES_KEY decKey; AES_set_decrypt_key(uk, 128, &decKey); char decIV[AES_BLOCK_SIZE] = {
0}; char *decData = malloc(1024); AES_cbc_encrypt(encData,decData, strlen(encData), &decKey, decIV, AES_DECRYPT); decData[strlen(inStr)] = '\0'; printf("dec:%s\n",decData); if (strcmp(inStr, decData)==0) { printf("PASS\n"); }

 

 

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

         功能非常完善。

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

       测试使用openssl 1.1.0c

  

转载于:https://www.cnblogs.com/cocoajin/p/6121706.html

你可能感兴趣的文章
怎么还原回收站删除的文件?这个操作最实用
查看>>
相机SD卡数据恢复,必知小技巧
查看>>
如何发送和接收 Windows Phone 的磁贴通知
查看>>
配置pxe自动化安装centos系统
查看>>
C语言之为数据类型定义别名
查看>>
HTML DOM 之 DOM对象:Document Object Model (文档对象模型)
查看>>
【网络编程】大端模式和小端模式(大头序和小头序)
查看>>
Angular之Rxjs基础操作
查看>>
U3D笔记(三)
查看>>
js date日期 英文月份
查看>>
我的友情链接
查看>>
ARM9-----如何烧录裸板程序
查看>>
window 2008 搭建winmail邮件系统配置
查看>>
多线程服务器的常用编程模型(转)
查看>>
k8s 如何 Failover?- 每天5分钟玩转 Docker 容器技术(127)
查看>>
C#List 泛型类使用(摘自MSDN)
查看>>
ubuntu下给php配置redis
查看>>
js 页面刷新location.reload和location.replace的区别小结
查看>>
我的友情链接
查看>>
Python OpenCV实例:马赛克效果
查看>>