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. 基于Spark Mllib,SparkSQL的电影推荐系统

    本文测试的Spark版本是1.3.1 本文将在Spark集群上搭建一个简单的小型的电影推荐系统,以为之后的完整项目做铺垫和知识积累 整个系统的工作流程描述如下: 1.某电影网站拥有可观的电影资源和用户 ...

  2. 虚拟机oracle virtualbox 上安装centos6.5 网络设置

    上篇文章写到,在虚拟机上安装centos6.5,结果依照文章非常顺利的安装了,可是用yum安装软件的时候.报错,源有问题,不能下载,然后ping一下摆渡.非常悲催 dns解析不了,cat /etc/r ...

  3. Bat 替换文件中的字符串

    echo off setlocal enabledelayedexpansion set "file=Config\__Config\server_config_common.xml&quo ...

  4. javaEE开发之文件下载

    package com.example.web; import java.io.File; import java.io.FileInputStream; import java.io.IOExcep ...

  5. java常用英语单词

    abstract (关键字) 抽象 ['.bstr.kt] access vt.访问,存取 ['.kses]'(n.入口,使用权) algorithm n.算法 ['.lg.riem] annotat ...

  6. activiti designer下载地址

    http://www.activiti.org/designer/update/ http://www.activiti.org/designer/archived/       这个地址貌似不能用了 ...

  7. 深入浅出理解之 onInterceptTouchEvent与onTouchEvent

    参考:http://blog.csdn.net/android_tutor/article/details/7193090   与   http://www.cnblogs.com/kingcent/ ...

  8. SVN学习(二)——SVN 提交、更新、解决冲突等操作步骤

    1. 纳入版本控制 ①新建文件abc.txt ②在文件上点右键 ③添加后文件图标发生变化 2. 提交 ①使用TortoiseSVN可以提交具体某一个文件,或某一个目录下的所有改变.方法就是在想要提交的 ...

  9. 硬件(MAC)地址的概念及作用

    概念:MAC地址就是在媒体接入层上使用的地址,也叫物理地址.硬件地址或链路地址,其被固化在适配器的ROM中. 可见MAC地址实际上就是适配器地址或适配器标识符.当某台计算机使用某块适配器后,适配器上的 ...

  10. MyBatis官方教程及源代码解析——mapper映射文件

    缓存 1.官方文档 MyBatis 包括一个非常强大的查询缓存特性,它能够非常方便地配置和定制. MyBatis 3 中的缓存实现的非常多改进都已经实现了,使得它更加强大并且易于配置. 默认情况下是没 ...