openssl为用户提供了丰富的指令,同时也提供了供编程调用的API,本文以使用128位aes算法的ecb模式进行加密和解密验证,如下所示

第一种方法,直接使用aes算法提供的api进行调用,代码如下

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <openssl/aes.h> int main(void)
{
char userkey[AES_BLOCK_SIZE];
unsigned char *date = malloc(AES_BLOCK_SIZE*);
unsigned char *encrypt = malloc(AES_BLOCK_SIZE* + );
unsigned char *plain = malloc(AES_BLOCK_SIZE*);
AES_KEY key; memset((void*)userkey, 'k', AES_BLOCK_SIZE);
memset((void*)date, 'p', AES_BLOCK_SIZE*);
memset((void*)encrypt, , AES_BLOCK_SIZE*);
memset((void*)plain, , AES_BLOCK_SIZE*); /*设置加密key及密钥长度*/
    AES_set_encrypt_key(userkey, AES_BLOCK_SIZE*, &key);

    int len = ;
/*循环加密,每次只能加密AES_BLOCK_SIZE长度的数据*/
while(len < AES_BLOCK_SIZE*) {
AES_encrypt(date+len, encrypt+len, &key);
len += AES_BLOCK_SIZE;
}
    /*设置解密key及密钥长度*/
AES_set_decrypt_key(userkey, AES_BLOCK_SIZE*, &key); len = ;
/*循环解密*/
while(len < AES_BLOCK_SIZE*) {
AES_decrypt(encrypt+len, plain+len, &key);
len += AES_BLOCK_SIZE;
}
    /*解密后与原数据是否一致*/
if(!memcmp(plain, date, AES_BLOCK_SIZE*)){
printf("test success\n");
}else{
printf("test failed\n");
} printf("encrypt: ");
int i = ;
for(i = ; i < AES_BLOCK_SIZE* + ; i++){
printf("%.2x ", encrypt[i]);
if((i+) % == ){
printf("\n");
}
}
printf("\n"); return ;
}

编译执行结果如下

xlzh@cmos:~/cmos/openssl-code/aes$ gcc aes.c -o aes.out -lssl -lcrypto
xlzh@cmos:~/cmos/openssl-code/aes$ ./aes.out
test success
encrypt: a9 4d b0 1b fe 3d e4 ed a9 4d b0 1b fe 3d e4 ed
a9 4d b0 1b fe 3d e4 ed
xlzh@cmos:~/cmos/openssl-code/aes$

第二种方法,使用EVP框架,示例如下

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <openssl/evp.h>
#include <openssl/aes.h> int main(void)
{
char userkey[EVP_MAX_KEY_LENGTH];
char iv[EVP_MAX_IV_LENGTH];
unsigned char *date = malloc(AES_BLOCK_SIZE*);
unsigned char *encrypt = malloc(AES_BLOCK_SIZE*);
unsigned char *plain = malloc(AES_BLOCK_SIZE*);
EVP_CIPHER_CTX ctx;
int ret;
int tlen = ;
int mlen = ;
int flen = ; memset((void*)userkey, 'k', EVP_MAX_KEY_LENGTH);
memset((void*)iv, 'i', EVP_MAX_IV_LENGTH);
memset((void*)date, 'p', AES_BLOCK_SIZE*);
memset((void*)encrypt, , AES_BLOCK_SIZE*);
memset((void*)plain, , AES_BLOCK_SIZE*); /*初始化ctx*/
    EVP_CIPHER_CTX_init(&ctx);

    /*指定加密算法及key和iv(此处IV没有用)*/
    ret = EVP_EncryptInit_ex(&ctx, EVP_aes_128_ecb(), NULL, userkey, iv);
if(ret != ) {
printf("EVP_EncryptInit_ex failed\n");
exit(-);
} /*禁用padding功能*/
EVP_CIPHER_CTX_set_padding(&ctx, );
/*进行加密操作*/
    ret = EVP_EncryptUpdate(&ctx, encrypt, &mlen, date, AES_BLOCK_SIZE*);
if(ret != ) {
printf("EVP_EncryptUpdate failed\n");
exit(-);
}
/*结束加密操作*/
ret = EVP_EncryptFinal_ex(&ctx, encrypt+mlen, &flen);
if(ret != ) {
printf("EVP_EncryptFinal_ex failed\n");
exit(-);
} tlen = mlen + flen; tlen = ;
mlen = ;
flen = ; EVP_CIPHER_CTX_cleanup(&ctx);
EVP_CIPHER_CTX_init(&ctx);
    ret = EVP_DecryptInit_ex(&ctx, EVP_aes_128_ecb(), NULL, userkey, iv);
if(ret != ) {
printf("EVP_DecryptInit_ex failed\n");
exit(-);
} EVP_CIPHER_CTX_set_padding(&ctx, );
ret = EVP_DecryptUpdate(&ctx, plain, &mlen, encrypt, AES_BLOCK_SIZE*);
if(ret != ) {
printf("EVP_DecryptUpdate failed\n");
exit(-);
} ret = EVP_DecryptFinal_ex(&ctx, plain+mlen, &flen);
if(ret != ) {
printf("EVP_DecryptFinal_ex failed\n");
exit(-);
}
    /*对比解密后与原数据是否一致*/
if(!memcmp(plain, date, AES_BLOCK_SIZE*)) {
printf("test success\n");
} else {
printf("test failed\n");
} printf("encrypt: ");
int i;
for(i = ; i < AES_BLOCK_SIZE*+; i ++){
printf("%.2x ", encrypt[i]);
if((i+)% == ){
printf("\n");
}
}
printf("\n"); return ;
}

编译执行结果如下:

xlzh@cmos:~/cmos/openssl-code/aes$ gcc evp.c -o evp.out -lssl -lcrypto
xlzh@cmos:~/cmos/openssl-code/aes$ ./evp.out
test success
encrypt: a9 4d b0 1b fe 3d e4 ed a9 4d b0 1b fe 3d e4 ed
a9 4d b0 1b fe 3d e4 ed
xlzh@cmos:~/cmos/openssl-code/aes$

EVP框架是对openssl提供的所有算法进行了封装,在使用工程中只需要修改少量的代码就可以选择不同的加密算法,在工作中通常采用这种方式。

在上述两个示例中,直接使用API提供的接口,没有使用padding,在EVP中同样需要声明不可以使用padding方式,否则即使要加密的数据长度是AES_BLOCK_SIZE的整数倍,EVP默认也会对原始数据进行追加,导致结果不同,所以在试验中通过EVP_CIPHER_CTX_set_padding(&ctx, )函数关闭的EVP的padding功能,同样在解密的时候也需要进行关闭。

openssl AES加密算法API的使用示例的更多相关文章

  1. [转]使用Openssl的AES加密算法

    转自:http://www.thinkemb.com/wordpress/?p=18 参考:http://blog.csdn.net/shuanyancao/article/details/89859 ...

  2. 使用Openssl的AES加密算法

    原文链接: http://blog.csdn.net/yasi_xi/article/details/13997337 Openssl是很常见的C接口的库,个人觉得易用.以下是AES加密的使用备忘.如 ...

  3. openssl 对称加密算法enc命令详解

    1.对称加密算法概述 openssl的加密算法库提供了丰富的对称加密算法,我们可以通过openssl提供的对称加密算法指令的方式使用,也可以通过调用openssl提供的API的方式使用. openss ...

  4. Openssl aes加解密例程

    原文链接: http://blog.csdn.net/itmes/article/details/7714854 假设我们已经下载了 openssl的源码,并成功编译,设置好了编程环境. 我们现在来看 ...

  5. iOS,Android,.NET通用AES加密算法

    原文:iOS,Android,.NET通用AES加密算法 这两天为移动App开发API,结果实现加密验证时碰到一大坑.这里不得不吐槽下又臭又硬的iOS,Windows Server无法解密出正确的结果 ...

  6. Openssl aes加解密例程 更进一步

    原文链接: http://blog.csdn.net/itmes/article/details/7718427 前面我们用openssl的aes256对称加密算法对16个字节的内存块进行了的加解密运 ...

  7. php RSA和AES加密算法

    一.RSA加密 RSA只说PHP中的应用,详细的算法原理解释,请自行百度,或者参考(RSA加密算法-详细解释以及公钥加密为什么每次都不一样) 总结:公钥加密.私钥解密.私钥签名.公钥验签. 注意: 1 ...

  8. AES加密算法C++实现

    我从网上下载了一套AES加密算法的C++实现,代码如下: (1)aes.h #ifndef SRC_UTILS_AES_H #define SRC_UTILS_AES_H class AES { pu ...

  9. demo工程的清单文件及activity中api代码简单示例

    第一步注册一个账户,并创建一个应用.获取app ID与 app Key. 第二步下载sdk 第三步新建工程,修改清单文件,导入相关的sdk文件及调用相应的api搞定. 3.1 修改清单文件,主要是加入 ...

随机推荐

  1. 分享一次在Windows Server2012 R2中安装SQL Server2008

    入手一台Windows Server2012云服务器,搭建一下服务环境,选用SQL Server2008 直奔主题,下好安装镜像后,直接双击 选择运行程序而不获取帮助 如图: 进入安装中心后选择 安装 ...

  2. OpenSuse下编译MonoDevelop

    当访问Monodevelop.com官网下载的安装包,安装后,发现并不是最新版.在OpenSuse下载的是3.0版本.根据官网的指示,可以自己下载源码进行编译.按官网的指引: 1. $ git clo ...

  3. 爆炸!iOS资源大礼包(持续更新...)

    今天为大家整理了一些关于iOS学习的干货,献给正在奋斗的你们,首先声明一下,在整理的过程中参考了大量的博客和文章,知识的分享终究会增值,在此表示感谢,希望这篇文章给大家带来帮助. 基础部分: C语言教 ...

  4. div+css不间断滚动字幕

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  5. ionic开发android app步骤

    一.android开发 1. 首先要安装node环境,Ionic的安装和后续的许多前端工具的安装都依赖于node的包管理器npm. nodeJs环境的安装很简单,去官网下载最新版的NodeJs直接安装 ...

  6. jQuery+Ajax+PHP+Mysql实现分页显示数据

    css <style type="text/css"> #loading{ position: absolute; top: 200px; left:400px; } ...

  7. pyqt5猜数游戏

    电脑随机生成4个互不相等的数,你猜. 1:你猜的数和正确答案相比,位置正确的个数 2:你猜的数虽然在正确答案中,但位置不对,它的个数. 代码如下: #!/usr/bin/env python # -* ...

  8. uc/os 笔记(转)

    1.uC/OS-II中使用互斥信号对象应该注意 互斥信号对象(Mutual Exclusion Semaphore)简称Mutex,是uC/OS-II的内核对象之一,用于管理那些需要独占访问的资源,并 ...

  9. AngularJS自定义表单验证器

    <!doctype html> <html ng-app="myApp"> <head> <script src="G:\\So ...

  10. Java学习笔记--HashMap中使用object做key的问题【转】

    在HashMap中,如果需要使用多个属性组合作为key,可以将这几个属性组合成一个对象作为key.但是存在的问题是,要做get时,往往没办法保存当初put操作时的key object的referenc ...