openssl的AES加密(base64编码)

【 base64编码/解码 】
AES加密后为乱码,使用base64编码后显示正常

/*************************************************Function:          base64EncodeDescription:        base64 编码Input:1.input          需编码的数据字符串2.length       实际长度(不可使用strlen求取,字符串中可能含有结束符等)3.newLineOutput:            Return:         转化后的字符串指针Others:
*************************************************/
char * base64Encode(const char *buffer, int length, bool newLine)
{BIO *bmem = NULL;BIO *b64 = NULL;BUF_MEM *bptr;b64 = BIO_new(BIO_f_base64());if (!newLine) {BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);}bmem = BIO_new(BIO_s_mem());b64 = BIO_push(b64, bmem);BIO_write(b64, buffer, length);BIO_flush(b64);BIO_get_mem_ptr(b64, &bptr);BIO_set_close(b64, BIO_NOCLOSE);char *buff = (char *)malloc(bptr->length + 1);memcpy(buff, bptr->data, bptr->length);buff[bptr->length] = 0;BIO_free_all(b64);return buff;
}/*************************************************Function:            base64DecodeDescription:        base64 解码Input:1.input          需解码的数据字符串2.length       实际长度(不可使用strlen求取,字符串中可能含有结束符等)3.newLineOutput:            Return:         转化后的字符串指针Others:
*************************************************/
char * base64Decode(char *input, int length, bool newLine)
{BIO *b64 = NULL;BIO *bmem = NULL;char *buffer = (char *)malloc(length);memset(buffer, 0, length);b64 = BIO_new(BIO_f_base64());if (!newLine) {BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);}bmem = BIO_new_mem_buf(input, length);bmem = BIO_push(b64, bmem);BIO_read(bmem, buffer, length);BIO_free_all(bmem);return buffer;
}

【 AES加密/解密 】
AES算法的块(block)的长度固定为16字节。假设一个字符串在AES加密前的长度为cleanLen,加密后的长度为cipherLen,则二者有下面的关系,其中的“/”是整除。

cipherLen = (clearLen/16 + 1) * 16
比如:(注意第二行,即使48刚好能被16整除,也要额外追加一个16字节的块)

clearLen cipherLen
47 48
48 64
49 64
#define AES_DEBUG/*************************************************Function:         aes_ecb_pkcs5padding_encryptDescription:        AES加密Input:Output:          Return:         Others:
*************************************************/
int aes_ecb_pkcs5padding_encrypt(const char *in, char *out, const unsigned char *key, const int keybits)
{AES_KEY aes;unsigned char *input_string;unsigned char *encrypt_string;unsigned int surplus_len;char b; char *tmp_out;const char *tmp_in;int encrypt_quit = 0;if(in == NULL || out == NULL){#ifdef AES_DEBUGprintf("[%s] [%d] \"in\" or \"out\" point error!!\n", __FILE__, __LINE__);#endif}input_string = (unsigned char*)calloc(AES_BLOCK_SIZE, sizeof(unsigned char));if (input_string == NULL) {#ifdef AES_DEBUGprintf("[%s] [%d] input_string error!!\n", __FILE__, __LINE__);#endiffprintf(stderr, "Unable to allocate memory for input_string\n");exit(-1);}encrypt_string = (unsigned char*)calloc(AES_BLOCK_SIZE, sizeof(unsigned char));if (encrypt_string == NULL) {#ifdef AES_DEBUGprintf("[%s] [%d] encrypt_string error!!\n", __FILE__, __LINE__);#endiffprintf(stderr, "Unable to allocate memory for encrypt_string\n");return -1;}memset(encrypt_string, 0, AES_BLOCK_SIZE);// set encrypt keyif (AES_set_encrypt_key(key, 128, &aes) < 0) {#ifdef AES_DEBUGprintf("[%s] [%d] AES_set_encrypt_key error!!\n", __FILE__, __LINE__);#endiffprintf(stderr, "Unable to set encryption key in AES\n");return -1;}tmp_in = in;tmp_out = out;while(!encrypt_quit){if(strlen(tmp_in) == 0){#ifdef AES_DEBUGprintf("[%s] [%d] (strlen(tmp_in) == 0) \n", __FILE__, __LINE__);#endifsurplus_len = AES_BLOCK_SIZE;b = '\0'+surplus_len;memset(input_string, b, AES_BLOCK_SIZE);encrypt_quit = 1;}else if(strlen(tmp_in)/AES_BLOCK_SIZE > 0){#ifdef AES_DEBUGprintf("[%s] [%d] (strlen(tmp_in)/AES_BLOCK_SIZE > 0) \n", __FILE__, __LINE__);#endifmemcpy(input_string, tmp_in, AES_BLOCK_SIZE);}else{// daisy 加密数据应为16字节的整数倍,若不是则需填充。//填充方式为:surplus_len = AES_BLOCK_SIZE - (strlen(tmp_in)%AES_BLOCK_SIZE)//(即以所需不齐的数值作为填充值,填充剩余空缺)#ifdef AES_DEBUGprintf("[%s] [%d] else \n", __FILE__, __LINE__);#endifsurplus_len = AES_BLOCK_SIZE - (strlen(tmp_in)%AES_BLOCK_SIZE);b = '\0'+surplus_len;memset(input_string, b, AES_BLOCK_SIZE);memcpy(input_string, tmp_in, strlen(tmp_in));encrypt_quit = 1;}#ifdef AES_DEBUGprintf("input_string: %s\n", input_string);#endifmemset(encrypt_string, 0, AES_BLOCK_SIZE);AES_ecb_encrypt(input_string, encrypt_string, &aes, AES_ENCRYPT);#ifdef AES_DEBUGprintf("encrypt_string: %s\n", encrypt_string);#endifmemcpy(tmp_out, encrypt_string, AES_BLOCK_SIZE);tmp_out += AES_BLOCK_SIZE;tmp_in += AES_BLOCK_SIZE;}free(input_string);free(encrypt_string);return 0;
}/*************************************************Function:            aes_ecb_pkcs5padding_decryptDescription:        AES解密Input:Output:          Return:         Others:
*************************************************/
int aes_ecb_pkcs5padding_decrypt(char* in, char* key, char* out)
{if(!in || !key || !out) return 0;AES_KEY aes;if(AES_set_decrypt_key((unsigned char*)key, 128, &aes) < 0){return 0;}int len=strlen(in), en_len=0;while(en_len<len){AES_decrypt((unsigned char*)in, (unsigned char*)out, &aes);in+=AES_BLOCK_SIZE;out+=AES_BLOCK_SIZE;en_len+=AES_BLOCK_SIZE;}return 1;
}

【 坑 】
AES加密后的实际长度(不可使用strlen求取,字符串中可能含有结束符等)
简单粗暴的方法。判断从当前指针指向的字符开始,往后3位均为空,则判定当前到达字符串末尾

【 实际调用接口 】

#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include "openssl/aes.h"void main()
{int num = 0;const unsigned char *aes_key = "1234567890123456";const char *data = "laodainiubi123456789";// 加密的数据char aes_encrypt_out[256];char aes_decrypt_out[256];memset(aes_encrypt_out, 0, sizeof(aes_encrypt_out));memset(aes_decrypt_out, 0, sizeof(aes_decrypt_out));printf("data = %s \n", data);aes_ecb_pkcs5padding_encrypt(data, aes_encrypt_out, aes_key, strlen(aes_key)*8);printf("aes_encrypt_out = %s  \n", aes_encrypt_out);// daisy 实际长度(不可使用strlen求取,字符串中可能含有结束符等)// 简单粗暴的方法。判断从当前指针指向的字符开始,往后3位均为空,则判定当前到达字符串末尾while(!((*(aes_encrypt_out + num) == NULL) && (*(aes_encrypt_out + num + 1) == NULL) \&& (*(aes_encrypt_out + num + 2) == NULL) && (*(aes_encrypt_out + num + 3) == NULL))){//      printf("*(aes_encrypt_out + %d) = %c \n", num, *(aes_encrypt_out + num));num++;}printf("num = %d \n", num);char * encode = base64Encode(aes_encrypt_out, num, false);printf("after base64Encode:%s\n", encode);char * decode = base64Decode(encode, strlen(encode), false);printf("after base64Decode:%s\n", decode);aes_ecb_pkcs5padding_decrypt(decode, aes_key, aes_decrypt_out);printf("aes_decrypt_out = %s  \n", aes_decrypt_out);
}

openssl的AES加密(base64编码)相关推荐

  1. AES加密 + Base64编码

    AES 加密 依赖: <dependency><groupId>commons-net</groupId><artifactId>commons-net ...

  2. des加密+base64编码,base64解码+des解密

    des加密+base64编码,base64解码+des解密 des简单介绍 base64简单介绍 运行效果图 TestActivity.java DataEncryptionUtil.java des ...

  3. openssl加密base64编码

    openssl OpenSSL 是一个安全套接字层密码库,囊括主要的密码算法.常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用. 首先,要安装 openssl: ce ...

  4. AES加密/解密报错,Input length must be multiple of 16 when decrypting with padded cipher

    背景:需要存储一个类似密钥的字符串,密文存储,并要求能逆向解密出来. 问题描述:使用AES对该字符串进行加密后生成byte数组,使用new String()方法转为字符串后存储到数据库. 从数据库中取 ...

  5. aes离线解密工具_如何在Python中解密OpenSSL AES加密文件?

    OpenSSL为AES加密提供了一种流行的(但不安全 - 见下文!)命令行界面: openssl aes-256-cbc -salt -in filename -out filename.enc Py ...

  6. openssl 加密解密 指令_openssl命令aes加密和解密

    openssl命令aes加密和解密 日期:2014-11-12 10:41:25 最后更新日期:2017-07-06 10:00:10 [技术] man openssl查看openssl的功能: [c ...

  7. linux下面C 利用openssl的AES库加密,解密

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

  8. MD5工具类 加盐加密 及编码

    titls: MD5工具类加密 date: 2018/11/12 10:03:42 categories: 开发module import java.security.MessageDigest; i ...

  9. openssl算法 —— 利用openssl进行BASE64编码解码、md5/sha1摘要、AES/DES3加密解密

    openssl 加密字符串的方法: 一.利用openssl命令进行BASE64编码解码(base64 encode/decode): 1. BASE64编码命令 对字符串'abc'进行base64编码 ...

最新文章

  1. 英文词频统计预备,组合数据类型练习
  2. 【安全漏洞】浅谈Bypass Waf (基础-实战)
  3. VTK修炼之道75:交互部件_测量类Widget的应用
  4. setTimeout and jquery
  5. 从BMW Vision iNEXT 看宝马如何进军自动驾驶
  6. 现在的00后都这么牛X的吗?
  7. CentOS 6 编译安装subversion-1.8.10+Apache2.4
  8. 虚拟化VMware ESXi 6.7服务器安装配置
  9. 新手 php连接数据库大概。简单过程浅析以及遇到的问题分析
  10. 大话设计模式--抽象工厂模式 Abstract Factory -- C++实现实例
  11. Pycharm主题,彩虹猫进度条,翻译插件
  12. [OT]ubuntu下安装HP-P1108打印机驱动
  13. 验证信用卡c语言,信用卡卡号验证算法
  14. CAD填充块Hatch的深度解析
  15. goldendict无法导入字典
  16. Python解炸金花问题
  17. 计算机教室英语手抄报,我的教室英语手抄报
  18. 在win2008中配置ServU
  19. 蒙提霍尔问题(The Monty Hall Problem)解析(贝叶斯分析、Python仿真)
  20. java计算机毕业设计智能医技预约系统源码+mysql数据库+系统+部署+lw文档

热门文章

  1. python日期和时间的操作方法
  2. Siemens-PLM-TeamCenter虚拟机安装与配置
  3. 读秀数据库的用法+全国图书馆参考咨询联盟
  4. 新增版本管理及版本对比,接口测试结果增加误报标记,MeterSphere开源持续测试平台v1.17.0发布
  5. HTML+CSS制作七夕情人节求婚动画(520情人节程序员表白)
  6. 长三角城市数字经济发展水平评估白皮书
  7. Linux进阶-FTP服务器源码搭建(pureftpd)
  8. 《李开复自传——世界因你不同》——试读章节pdf下载
  9. 理光Ricoh Aficio MP 2852 一体机驱动
  10. Linux mkdir命令