OpenSSL提供了AES加解密算法的API

const char *AES_options(void);

AES算法状态,是所有支持或者是部分支持。

返回值:“aes(full)” 或者"aes(partial)"

int AES_set_encrypt_key(const unsigned char *userKey, const int bits,AES_KEY *key);

设定加密用的Key;

userKey: 密钥数值。

bits:密钥长度,以bit为单位。假设密钥数字是16个字节,则此參数值应为128。

key: AES_KEY对象指针;

返回值: 0 成功, -1 userkey,key为空, -2: 密钥长度不是128。192。256;

int AES_set_decrypt_key(const unsigned char *userKey, const int bits,  AES_KEY *key);

设定解密用的Key;

userKey: 密钥数值;

bits:密钥长度,以bit为单位,假设密钥数字是16个字节。则此參数值应为128;

key: AES_KEY对象指针;

返回值: 0 成功, -1 userkey。key为空。 -2: 密钥长度不是128。192,256。

void AES_encrypt(const unsigned char *in, unsigned char *out,const AES_KEY *key);

AES 加密。加密单个数据块。in,out能够是同一内存区;

in: 须要加密的数据;

out: 加密后的数据。

key:AES 密钥。

void AES_decrypt(const unsigned char *in, unsigned char *out,const AES_KEY *key);

AES 解密。解密单个数据块,in。out能够是同一内存区;

in: 须要解密的数据。

out: 解密后的数据;

key:AES 密钥。

void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,    const AES_KEY *key, const int enc);

AES加密/解密单个数据块,ECB模式

in: 须要加密/解密的数据;

out: 计算后输出的数据。

key:密钥

enc: AES_ENCRYPT 代表加密, AES_DECRYPT代表解密。

void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,   size_t length, const AES_KEY *key,    unsigned char *ivec, const int enc);

AES加密/解密单个数据块,CBC模式

in: 须要加密/解密的数据;

out: 计算后输出的数据。

length: 数据长度

key:密钥

ivec: 初始向量

enc: AES_ENCRYPT 代表加密, AES_DECRYPT代表解密;

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);

AES CFB128位模式加密/解密。输入输出数据区能够重叠。

in: 须要加密/解密的数据。

out: 计算后输出的数据;

length: 数据长度;

key: 密钥;

ivec: 初始化向量

num: 输出參数。计算状态。多少个CFB数据块

enc: 计算模式。 加密: AES_ENCRYPT 。 解密: AES_DECRYPT

    

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);

AES CFB1位模式加密/解密。输入输出数据区能够重叠;

in: 须要加密/解密的数据;

out: 计算后输出的数据;

length: 数据长度;

key: 密钥;

ivec: 初始化向量

num: 输出參数,计算状态,多少个CFB数据块

enc: 计算模式, 加密: AES_ENCRYPT , 解密: AES_DECRYPT

    

    

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);

AES CFB8位模式加密/解密。输入输出数据区能够重叠;

in: 须要加密/解密的数据;

out: 计算后输出的数据;

length: 数据长度;

key: 密钥;

ivec: 初始化向量

num: 输出參数,计算状态,多少个CFB数据块

enc: 计算模式, 加密: AES_ENCRYPT , 解密: AES_DECRYPT



    

void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,

    size_t length, const AES_KEY *key,

    unsigned char *ivec, int *num);

AES OFB128位模式加密/解密,输入输出数据区能够重叠;

in: 须要加密/解密的数据;

out: 计算后输出的数据。

length: 数据长度;

key: 密钥。

ivec: 初始化向量

num: 输出參数,计算状态,多少个CFB数据块

enc: 计算模式, 加密: AES_ENCRYPT , 解密: AES_DECRYPT



        

    

void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,

    size_t length, const AES_KEY *key,

    unsigned char ivec[AES_BLOCK_SIZE],

    unsigned char ecount_buf[AES_BLOCK_SIZE],

    unsigned int *num);

AES CTR128位模式加密/解密,输入输出数据区能够重叠;

in: 须要加密/解密的数据。

out: 计算后输出的数据;

length: 数据长度;

key: 密钥。

ivec: 初始化向量

ecount_buf: 输出參加,加密的次数,在第一次调用此函数时,须要初始化为0

num: 输出參数,计算状态,多少个CFB数据块,在第一次调用此函数时,须要初始化为0

enc: 计算模式。 加密: AES_ENCRYPT , 解密: AES_DECRYPT







void AES_ige_encrypt(const unsigned char *in, unsigned char *out,

             size_t length, const AES_KEY *key,

             unsigned char *ivec, const int enc);

AES 加密/解密,输入输出数据区能够重叠,初始化向量是加密数据块的2倍,加密前用前半部分做一次异或。加密后用后半部分做一次异或;

in: 须要加密/解密的数据;

out: 计算后输出的数据。

length: 数据长度;

key: 密钥;

ivec: 初始化向量

enc: 计算模式。 加密: AES_ENCRYPT , 解密: AES_DECRYPT

    

                 



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);

AES 加密/解密。输入输出数据区能够重叠。初始化向量是加密数据块的4倍,加密前用第一部分做一次异或。加密后用第二部分做一次异或;

最后一个加密数据块,加密前用第三部分异或,加密后用第四部分异或;

in: 须要加密/解密的数据;

out: 计算后输出的数据;

length: 数据长度。

key: 密钥。

ivec: 初始化向量

enc: 计算模式, 加密: AES_ENCRYPT , 解密: AES_DECRYPT

int AES_wrap_key(AES_KEY *key, const unsigned char *iv,

        unsigned char *out,

        const unsigned char *in, unsigned int inlen)

用AES算法对明文key数据加密

key: AES Key,用于加密密钥数据

iv: 初始化向量

out: 加密后的密钥数据

in: 密钥数据

inlen: 密钥数据长度

返回值: 1: 成功。 0: 失败

int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,

        unsigned char *out,

        const unsigned char *in, unsigned int inlen)

用AES算法对明文key数据加密

key: AES Key,用于加密密钥数据

iv: 初始化向量

out: 加密后的密钥数据

in: 密钥数据

inlen: 密钥数据长度

返回值: 1: 成功, 0: 失败

C实例分析:

首先要了解AES加密是什么。以及几种加密模式的差别。之后才是编程。

详细的编程案例,在以下的链接。

openssl之aes加密(AES_cbc_encrypt 与 AES_encrypt 的编程案例)

以下这个链接有具体图解。

http://www.cnblogs.com/adylee/archive/2007/09/14/893438.html

ECB模式 
  长处: 
  1.简单; 
  2.有利于并行计算。 
  3.误差不会被传送。 
  缺点: 
  1.不能隐藏明文的模式; 
  2.可能对明文进行主动攻击; 
CBC模式: 
  长处: 
  1.不easy主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。 
  缺点: 
  1.不利于并行计算。 
  2.误差传递。 
  3.须要初始化向量IV 
CFB模式: 
  长处: 
  1.隐藏了明文模式; 
  2.分组password转化为流模式; 
  3.能够及时加密传送小于分组的数据; 
  缺点: 
  1.不利于并行计算; 
  2.误差传送:一个明文单元损坏影响多个单元; 
  3.唯一的IV; 
ofb模式: 
  长处: 
  1.隐藏了明文模式; 
  2.分组password转化为流模式; 
  3.能够及时加密传送小于分组的数据; 
  缺点: 
  1.不利于并行计算; 
  2.对明文的主动攻击是可能的; 
  3.误差传送:一个明文单元损坏影响多个单元; 


了解这些加密模式之后,再看openssl提供的接口就好理解了。

下面接口来自“crypto/aes/aes.h”。有openssl源代码。
//设置加密和解密器
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);
void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char ivec[AES_BLOCK_SIZE],
unsigned char ecount_buf[AES_BLOCK_SIZE],
unsigned int *num);

从以下这个文件能够看出,AES_encrypt就是ecb加密的方式。而AES_set_encrypt_key和AES_encrypt,它们的实如今"crypto/aes/aes_x86core.c"和"crypto/aes/aes_core.c",也就是有两个版本号,依据平台选择。

看源代码。

调用实例:
  1. int aes_encrypt(char* in, char* key, char* out)//, int olen)
  2. {
  3. if(!in || !key || !out) return 0;
  4. AES_KEY aes;
  5. if(AES_set_encrypt_key((unsigned char*)key, 128, &aes) < 0)
  6. {
  7. return 0;
  8. }
  9. int len=strlen(in), en_len=0;
  10. while(en_len<len)//输入输出字符串够长。而且是AES_BLOCK_SIZE的整数倍,须要严格限制
  11. {
  12. AES_encrypt((unsigned char*)in, (unsigned char*)out, &aes);
  13. in+=AES_BLOCK_SIZE;
  14. out+=AES_BLOCK_SIZE;
  15. en_len+=AES_BLOCK_SIZE;
  16. }
  17. return 1;
  18. }
  19. int aes_decrypt(char* in, char* key, char* out)
  20. {
  21. if(!in || !key || !out) return 0;
  22. AES_KEY aes;
  23. if(AES_set_decrypt_key((unsigned char*)key, 128, &aes) < 0)
  24. {
  25. return 0;
  26. }
  27. int len=strlen(in), en_len=0;
  28. while(en_len<len)
  29. {
  30. AES_decrypt((unsigned char*)in, (unsigned char*)out, &aes);
  31. in+=AES_BLOCK_SIZE;
  32. out+=AES_BLOCK_SIZE;
  33. en_len+=AES_BLOCK_SIZE;
  34. }
  35. return 1;
  36. }

最后给出一个链接,利用openssl的AES接口进行编程。

參考资料:

分组对称加密模式:ECB/CBC/CFB/OFB缺CTR

http://fossies.org/dox/openssl-1.0.1f/index.html (具体源代码)

命令行下openssl对文件加密解密:

--建立文件test.txt, 特意写入中英文



# cd /tmp



# echo "test測试" > test.txt



--開始加密, 使用aes-128-cbc算法, 也能够使用其它算法, 通过查看openssl的帮助可获知



# openssl aes-128-cbc -salt -in test.txt -out test.txt.aes

enter aes-128-cbc encryption password:<输入密码>

Verifying - enter aes-128-cbc encryption password:<确认密码>



--查看加密前后的文件大小, 加密后文件明显增大了



# ll test.txt*  

-rw-r--r--  1 root root  9 Aug 11 15:42 test.txt

-rw-r--r--  1 root root 32 Aug 11 15:43 test.txt.aes



--查看加密前后的文件内容, 加密后文件无法直接查看, 显示乱码



# cat test.txt

test測试



# cat test.txt.aes

Salted__碾RTqm6棚顱



--如今開始解密, 会提示输入password, 假设password有误则无法解密



# openssl aes-128-cbc -d -salt -in test.txt.aes -out test.txt.out

enter aes-128-cbc decryption password:<输入错误密码>

bad decrypt

6150:error:06065064:digital envelope routines:EVP_DecryptFinal:bad decrypt:evp_enc.c:438:



# openssl aes-128-cbc -d -salt -in test.txt.aes -out test.txt.out

enter aes-128-cbc decryption password:<输入正确密码>



--查看解密前后的文件大小, 和加密前是一样的



# ll test.txt*

-rw-r--r--  1 root root  9 Aug 11 15:42 test.txt

-rw-r--r--  1 root root 32 Aug 11 15:43 test.txt.aes

-rw-r--r--  1 root root  9 Aug 11 15:45 test.txt.out



--查看解密前后的文件内容, 和加密前是一样的



# cat test.txt.out

test測试



这样的方法很适合Linux下的文件内容保密, 呵呵....以上命令加參数比較复杂, 我们能够把命令加參数做个函数, 然后放到.bash_profile里, 这样每次登陆后直接使用函数就可以, 例如以下:

function jiami()

{

/usr/bin/openssl aes-128-cbc -salt -in $1 -out $1.aes && rm -f $1

}

function jiemi()

{

/usr/bin/openssl aes-128-cbc -d -salt -in $1.aes -out $1 && rm -f $1.aes

}

然后就能够例如以下使用了(注意输入參数都是原文件名称, 且会自己主动删除原文件):



# jiami test.txt

enter aes-128-cbc encryption password:

Verifying - enter aes-128-cbc encryption password:



# jiemi test.txt

enter aes-128-cbc decryption password:



# ll test.txt*  

-rw-r--r--  1 root root 9 Aug 11 15:46 test.txt

-rw-r--r--  1 root root 9 Aug 11 15:45 test.txt.out



--End--

linux以下C 利用openssl的AES库加密,解密的更多相关文章

  1. JS和利用openssl的object C加密得到相同的aes加密密文

    这是之前接到的一个工作内容,项目原本的登录操作是获得账号和密码以后,对密码进行一遍MD5加密,然后传递账号和密文到cgi文件.在c中获取到账户以后,从数据库中获取到密码,对密码进行一次MD5的加密,然 ...

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

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  3. PHP7.* AES的加密解密

    之前写过一篇: PHP AES的加密解密-----[弃用] 使用的是php5.*之前的mcrypt_decrypt 函数,该函数已经在php7.1后弃用了,上马的是openssl的openssl_en ...

  4. PHP AES的加密解密

    AES加密算法 密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替代原先的DE ...

  5. Golang之AES/DES加密解密

    AES/DES加密/解密涉及4个概念:1. Block, 也叫分组, 相应加密/解密的算法. 2. BlockMode, 模式, 相应加密/解密的处理.3. InitalVectory, 初始向量4. ...

  6. AES在线加密解密-附AES128,192,256,CBC,CFB,ECB,OFB,PCBC各种加密解密源码

    一.AES在线加密解密:AES 128/192/256位CBC/CFB/ECB/OFB/PCBC在线加密解密|在线工具|在线助手|在线生成|在线制作 http://www.it399.com/aes ...

  7. PHP AES的加密解密-----【弃用】

    mcrypt_decrypt在PHP7.*已经被弃用,取而代之的是openssl_decrypt/encrypt,请参考: PHP7.* AES的加密解密 AES加密算法 密码学中的高级加密标准(Ad ...

  8. PHP 服务端 和 APP 客户端 实现 RSA+AES 双向加密解密

    目的:服务端和移动端双向加密解密 共有七个文件 其中包括三个类文件 lib_aes.php aes对称加密解密类 server_rsa_crypt.php 服务端RSA公钥私钥非对称加密解密类 cli ...

  9. AES对称加密解密类

    import java.io.UnsupportedEncodingException; import javax.crypto.Cipher; import javax.crypto.spec.Se ...

随机推荐

  1. 利用github和git命令,将本地项目共享到服务器上

    一.步骤 1. 创建项目根目录 mkdir 文件夹名 2. 初始化文件夹 git init 3. 配置用户名和邮箱(第一次配置后,不需要再登录) git config user.name 名字 git ...

  2. idea tomcat 怎样出现update classes and resources

    idea Tomcat 出现update classes and resources 出现热加载 正确配置应该是这个 在 Deployment (调度,部署) 中点击 + 选择war explored ...

  3. [Android] 给图像加入相框、圆形圆角显示图片、图像合成知识

        前一篇文章讲述了Android触屏setOnTouchListener实现突破缩放.移动.绘制和加入水印,继续我的"随手拍"项目完毕给图片加入相框.圆形圆角显示图片和图像合 ...

  4. python对象序列化或持久化的方法

    http://blog.csdn.net/chen_lovelotus/article/details/7233293 一.Python对象持久化方法 目前为止,据我所知,在python中对象持久化有 ...

  5. 使用Google-Authenticator加强serverSSH登录

    对于须要特殊加密的人群,我这里给出对应的方法来进行谷歌式加密. 过程例如以下: 准备: 首先在你的手机上准备好client(自己百度下载) 接下来依照命令做: date 查看系统时间       da ...

  6. Django——WEB三层架构与MVC

    而我发此文的目的有二:一者,让初学者能够听到一家之言,是为解惑:二者,更希望抛砖引玉,得到专家的批判. 许多学生经常问我,MVC到底和WEB三层架构有啥关系? 开始时,我也只能给他们一些模糊的回答.时 ...

  7. Linux——.bash_profile和.bashrc的区别(如何设置生效)

    /etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行.并从/etc/profile.d目录的配置文件中搜集shell的设置./etc/bashrc:为每一个运 ...

  8. Django——如何处理请求(URL配置和视图)

    URLconfig—— 为了绑定视图函数和URL,我们使用URLconf. URLconf 就像是 Django 所支撑网站的目录. 它的本质是 URL 模式以及要为该 URL 模式调用的视图函数之间 ...

  9. 表单提交post和get方法区别

    表象不同,get把提交的数据url可以看到,post看不到 原理不同,get 是拼接 url, post 是放入http 请求体中 提交数据量不同,get最多提交2k数据,浏览器的限制.post理论上 ...

  10. 【Python3 爬虫】05_安装Scrapy

    Scrapy简介 Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛.框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容 ...