openssl AES加密算法API的使用示例
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的使用示例的更多相关文章
- [转]使用Openssl的AES加密算法
转自:http://www.thinkemb.com/wordpress/?p=18 参考:http://blog.csdn.net/shuanyancao/article/details/89859 ...
- 使用Openssl的AES加密算法
原文链接: http://blog.csdn.net/yasi_xi/article/details/13997337 Openssl是很常见的C接口的库,个人觉得易用.以下是AES加密的使用备忘.如 ...
- openssl 对称加密算法enc命令详解
1.对称加密算法概述 openssl的加密算法库提供了丰富的对称加密算法,我们可以通过openssl提供的对称加密算法指令的方式使用,也可以通过调用openssl提供的API的方式使用. openss ...
- Openssl aes加解密例程
原文链接: http://blog.csdn.net/itmes/article/details/7714854 假设我们已经下载了 openssl的源码,并成功编译,设置好了编程环境. 我们现在来看 ...
- iOS,Android,.NET通用AES加密算法
原文:iOS,Android,.NET通用AES加密算法 这两天为移动App开发API,结果实现加密验证时碰到一大坑.这里不得不吐槽下又臭又硬的iOS,Windows Server无法解密出正确的结果 ...
- Openssl aes加解密例程 更进一步
原文链接: http://blog.csdn.net/itmes/article/details/7718427 前面我们用openssl的aes256对称加密算法对16个字节的内存块进行了的加解密运 ...
- php RSA和AES加密算法
一.RSA加密 RSA只说PHP中的应用,详细的算法原理解释,请自行百度,或者参考(RSA加密算法-详细解释以及公钥加密为什么每次都不一样) 总结:公钥加密.私钥解密.私钥签名.公钥验签. 注意: 1 ...
- AES加密算法C++实现
我从网上下载了一套AES加密算法的C++实现,代码如下: (1)aes.h #ifndef SRC_UTILS_AES_H #define SRC_UTILS_AES_H class AES { pu ...
- demo工程的清单文件及activity中api代码简单示例
第一步注册一个账户,并创建一个应用.获取app ID与 app Key. 第二步下载sdk 第三步新建工程,修改清单文件,导入相关的sdk文件及调用相应的api搞定. 3.1 修改清单文件,主要是加入 ...
随机推荐
- typedef std::string AddressLines[4]定义了一个string数组,大小为4
int main() { typedef std::]; std::]; std::string *pal1 = new AddressLines; delete [] pal; delete [] ...
- python类方法与对象方法学习
class Test_Demo: TEST = 'test_value' def __init__(self,name,age): self.name = name self.age = age #s ...
- ECSTORE2.0 新增自定义定时任务
在ECsotre系统里面添加一个自定义的定时任务,可以完成一些自动化处理,例如自动确认订单或者是删除无效订单的,可以很方便的实现各种定时执行的任务,下面简单介绍下怎么添加定时任务. 在自己的app目录 ...
- 你不了解PHP的10件事情
看到有人翻译的<10 things you (probably) didn’t know about PHP>,发现在此次之前2.8两条并不知道,1.3虽然熟知但是去没有实际应用. 由于阅 ...
- c++ 连接数据库
#include <icrsint.h> #include<iostream> #include<iomanip> #include <string> ...
- 程序设计C 实验三 题目九 方程式(0300)
Description: Consider equations having the following form: a*x1*x1 + b*x2*x2 + c*x3*x3 + d*x4*x4 = 0 ...
- [工具] 解决sublime text运行javascript console无输出问题
1.使用nodeJS在sublime text 运行javascript 下载安装nodeJS 在sublime text新建build system:tools->build system-& ...
- cf Strings of Power
http://codeforces.com/contest/318/problem/B #include <cstdio> #include <cstring> #includ ...
- Powershell访问数组
数组的元素可以使用索引寻址,第一个元素的索引为0,第i个元素的索引为i-1,最后一个元素的索引为Count-1,但是Powershell为了使用方便,直接可以将 -1 作为最后的一个元素的索引. PS ...
- cocos2d-x Loading界面实现资源加载
有时候场景中的资源加载过多的话就会引起游戏进入的时候很卡,因为那是边加载边显示.在tests例子里面有一个很好的例子叫做TextureCacheTest,里面讲解了如何写loading. #inclu ...