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. Oracle怎样方便地查看报警日志错误

    由于报警日志文件很大,而每天都应该查看报警日志(查看有无“ORA-”,Error”,“Failed”等出错信息),故想找到一种比较便捷的方法,查看当天报警日志都有哪些错误. 在网上查了几天的资料,尝试 ...

  2. OC基础 内存管理

    OC基础  内存管理 我们所了解的c语言内存管理,如下: (1)c语言的内存分配:char *p = (char*)malloc(100*sizeof(char)); (2)c语言的内存释放:free ...

  3. [转]Swift编程风格指南

    语言 使用美式英语拼写以匹配苹果公司的API 优选: var color = "red" 不建议使用: var colour = "red" 间隔 使用2个空格 ...

  4. [JavaScript] 判断键盘同时按某些键时执行操作。

    前言:之前知乎上看到过一个介绍国外炫酷网站的,其中一个敏感网站用同时按住"q.a.p.l" 才能观看视频 放手则立即强制停止 (手动斜眼).这个功能的实际用处,我认为是可以在做一些 ...

  5. JS nodeType返回类型(复制的

    http://blog.csdn.net/qyf_5445/article/details/9232907 将HTML DOM中几个容易常用的属性做下记录: nodeName.nodeValue 以及 ...

  6. 分享8款精美的jQuery图片播放插件

    本文将和大家一起分享8款精美的jQuery图片播放插件,每一款插件均有演示和源码下载,有兴趣的朋友可以下载使用和研究.废话不多说了,直接上这些插件. 1.3D轮播相册 这款3D相册插件利用了HTML5 ...

  7. Spring MVC异常处理

    Spring Mvc 中异常处理,一般有两种解决办法: 一.利用org.springframework.web.servlet.handler.SimpleMappingExceptionResolv ...

  8. CentOS 5上Apache配置虚拟主机范例

    昨天实践了下在CentOS 5上通过Apache直接配置虚拟主机,服务器没有安装面板软件,所以只能通过SSH远程连接操作了.Apache安装在/etc/httpd目录下,这个即是Apache的根目录, ...

  9. Javascript中的对象和原型

    一 原型对象 原型对象实际上就是构造函数的一个实例对象,和普通的实例对象没有本质上的区别.可以包含特定类型的所有实例的共享属性或者方法.这样,如果我们需要修改所有实例中的属性或者方法,就只需要修改一处 ...

  10. dll signing issue

    1. Verify if a dll has been signed sn.exe -v module.dll Scenario: sometimes for security reasons, a ...