转自http://blog.csdn.net/chary8088/article/details/21124495
首先要了解AES加密是什么,以及几种加密模式的区别。之后才是编程。具体的编程案例,在下面的链接。
openssl之aes加密(AES_cbc_encrypt 与 AES_encrypt 的编程案例)
下面这个链接有详细图解。
http://fossies.org/dox/openssl-1.0.1f/index.html
(详细源码)
http://www.cnblogs.com/adylee/archive/2007/09/14/893438.html
最近遇到一个坑,
就是这两个函数让我折腾了四五天,心力憔悴,几近崩溃,也许是走火入魔了,因为遇到了挑战,非要干掉它,而不是绕过!
<p style="margin-top: 0px; margin-bottom: 10px; padding-top: 0px; padding-bottom: 0px;"><span class="pln" style="color: rgb(0, 0, 0);">AES</span><span class="pun" style="color: rgb(102, 102, 0);">加密<a target=_blank href="http://lib.csdn.net/base/datastructure" class="replace_word" title="算法与数据结构知识库" target="_blank" style="text-decoration: none; color: rgb(223, 52, 52); font-weight: bold;">算法</a></span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">-</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">加密模式</span></p>
ECB模式
优点:
1.简单;
2.有利于并行计算;
3.误差不会被传送;
缺点:
1.不能隐藏明文的模式;
2.可能对明文进行主动攻击;
CBC模式:
优点:
1.不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。
缺点:
1.不利于并行计算;
2.误差传递;
3.
需要初始化向量IV
CFB模式:
优点:
1.隐藏了明文模式;
2.分组密码转化为流模式;
3.可以及时加密传送小于分组的数据;
缺点:
1.不利于并行计算;
2.误差传送:一个明文单元损坏影响多个单元;
3.唯一的IV;
ofb模式:
优点:
1.隐藏了明文模式;
2.分组密码转化为流模式;
3.可以及时加密传送小于分组的数据;
缺点:
1.不利于并行计算;
2.对明文的主动攻击是可能的;
3.误差传送:一个明文单元损坏影响多个单元;
了解这些加密模式之后,再看openssl提供的接口就好理解了。
<p style="margin-top: 0px; margin-bottom: 10px; padding-top: 0px; padding-bottom: 0px;"><span class="pln" style="color: rgb(0, 0, 0);">openssl</span><span class="pun" style="color: rgb(102, 102, 0);">提供的</span><span class="pln" style="color: rgb(0, 0, 0);">aes</span><span class="pun" style="color: rgb(102, 102, 0);">加密接口</span></p>
以下接口来自“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",也就是有两个版本,根据平台选择。看源码。
<p style="margin-top: 0px; margin-bottom: 10px; padding-top: 0px; padding-bottom: 0px;"></p><div><span class="str" style="color: rgb(0, 136, 0);">"</span><span style="font-family: "Hiragino Sans GB W3", "Hiragino Sans GB", Arial, Helvetica, simsun, 宋体; white-space: normal;"><span class="str" style="color: rgb(0, 136, 0);">crypto/aes/</span></span><span style="font-family: "Hiragino Sans GB W3", "Hiragino Sans GB", Arial, Helvetica, simsun, 宋体;"><span class="str" style="color: rgb(0, 136, 0);">aes_ecb.c"</span></span></div><div><span class="kwd" style="color: rgb(0, 0, 136);">void</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(255, 0, 0);"><span class="pln" style="color: rgb(0, 0, 0);">AES_ecb_encrypt</span></span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">const</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">unsigned</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">char</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">*</span><span class="kwd" style="color: rgb(0, 0, 136);">in</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">unsigned</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">char</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">*</span><span class="kwd" style="color: rgb(0, 0, 136);">out</span><span class="pun" style="color: rgb(102, 102, 0);">,</span></div><div><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">const</span><span class="pln" style="color: rgb(0, 0, 0);"> AES_KEY </span><span class="pun" style="color: rgb(102, 102, 0);">*</span><span class="pln" style="color: rgb(0, 0, 0);">key</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">const</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> enc</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span></div><div><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">assert</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">in</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">&&</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">out</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">&&</span><span class="pln" style="color: rgb(0, 0, 0);"> key</span><span class="pun" style="color: rgb(102, 102, 0);">);</span></div><div><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">assert</span><span class="pun" style="color: rgb(102, 102, 0);">((</span><span class="pln" style="color: rgb(0, 0, 0);">AES_ENCRYPT </span><span class="pun" style="color: rgb(102, 102, 0);">==</span><span class="pln" style="color: rgb(0, 0, 0);"> enc</span><span class="pun" style="color: rgb(102, 102, 0);">)||(</span><span class="pln" style="color: rgb(0, 0, 0);">AES_DECRYPT </span><span class="pun" style="color: rgb(102, 102, 0);">==</span><span class="pln" style="color: rgb(0, 0, 0);"> enc</span><span class="pun" style="color: rgb(102, 102, 0);">));</span></div><div><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">AES_ENCRYPT </span><span class="pun" style="color: rgb(102, 102, 0);">==</span><span class="pln" style="color: rgb(0, 0, 0);"> enc</span><span class="pun" style="color: rgb(102, 102, 0);">)</span></div><div><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pln" style="color: rgb(0, 0, 0);">AES_encrypt</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">in</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">out</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> key</span><span class="pun" style="color: rgb(102, 102, 0);">);</span></div><div><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">else</span></div><div><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pln" style="color: rgb(0, 0, 0);">AES_decrypt</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">in</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">out</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> key</span><span class="pun" style="color: rgb(102, 102, 0);">);</span></div><div><span class="pun" style="color: rgb(102, 102, 0);">}</span></div><div><strong><span style="color: rgb(255, 0, 0);"><span class="pun" style="color: rgb(102, 102, 0);">从这里可以看出,</span><span class="pln" style="color: rgb(0, 0, 0);">ecb</span><span class="pun" style="color: rgb(102, 102, 0);">方式的加密,是由</span><span class="pln" style="color: rgb(0, 0, 0);">AES_encrypt</span><span class="pun" style="color: rgb(102, 102, 0);">接口实现的。</span></span></strong></div><p style="margin-top: 0px; margin-bottom: 10px; padding-top: 0px; padding-bottom: 0px;"></p>
而cbc的加密方式在另外的地方实现了,下面给出目录以及源代码。
<span style="font-family: "Hiragino Sans GB W3", "Hiragino Sans GB", Arial, Helvetica, simsun, 宋体;"><span class="str" style="color: rgb(0, 136, 0);">"</span></span><span style="font-family: "Hiragino Sans GB W3", "Hiragino Sans GB", Arial, Helvetica, simsun, 宋体; white-space: normal;"><span class="str" style="color: rgb(0, 136, 0);">crypto/aes/</span></span><span style="font-family: "Hiragino Sans GB W3", "Hiragino Sans GB", Arial, Helvetica, simsun, 宋体;"><span class="str" style="color: rgb(0, 136, 0);">aes_cbc.c"</span></span> <p style="margin-top: 0px; margin-bottom: 10px; padding-top: 0px; padding-bottom: 0px;"><span class="kwd" style="color: rgb(0, 0, 136);">void</span><span class="pln" style="color: rgb(0, 0, 0);"> AES_cbc_encrypt</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">const</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">unsigned</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">char</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">*</span><span class="kwd" style="color: rgb(0, 0, 136);">in</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">unsigned</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">char</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">*</span><span class="kwd" style="color: rgb(0, 0, 136);">out</span><span class="pun" style="color: rgb(102, 102, 0);">,</span> <span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">size_t</span><span class="pln" style="color: rgb(0, 0, 0);"> len</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">const</span><span class="pln" style="color: rgb(0, 0, 0);"> AES_KEY </span><span class="pun" style="color: rgb(102, 102, 0);">*</span><span class="pln" style="color: rgb(0, 0, 0);">key</span><span class="pun" style="color: rgb(102, 102, 0);">,</span> <span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">unsigned</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">char</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">*</span><span class="pln" style="color: rgb(0, 0, 0);">ivec</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">const</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> enc</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span> <span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">enc</span><span class="pun" style="color: rgb(102, 102, 0);">)</span> <span class="pln" style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(255, 0, 0);"><span class="pln" style="color: rgb(0, 0, 0);">CRYPTO_cbc128_encrypt</span></span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">in</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="kwd" style="color: rgb(0, 0, 136);">out</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">len</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">key</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">ivec</span><span class="pun" style="color: rgb(102, 102, 0);">,(</span><span class="pln" style="color: rgb(0, 0, 0);">block128_f</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">AES_encrypt</span><span class="pun" style="color: rgb(102, 102, 0);">);</span> <span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">else</span> <span class="pln" style="color: rgb(0, 0, 0);"> CRYPTO_cbc128_decrypt</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">in</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="kwd" style="color: rgb(0, 0, 136);">out</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">len</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">key</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">ivec</span><span class="pun" style="color: rgb(102, 102, 0);">,(</span><span class="pln" style="color: rgb(0, 0, 0);">block128_f</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">AES_decrypt</span><span class="pun" style="color: rgb(102, 102, 0);">);</span> <span class="pun" style="color: rgb(102, 102, 0);">}</span></p><p style="margin-top: 0px; margin-bottom: 10px; padding-top: 0px; padding-bottom: 0px;"><span style="font-weight: bold;"><span style="color: rgb(255, 0, 0);"><span class="pun" style="color: rgb(102, 102, 0);">从这里看出,</span><span style="font-family: "Hiragino Sans GB W3", "Hiragino Sans GB", Arial, Helvetica, simsun, 宋体;"><span class="pln" style="color: rgb(0, 0, 0);">cbc</span><span class="pun" style="color: rgb(102, 102, 0);">加密方式,调用接口</span></span><span style="font-family: "Hiragino Sans GB W3", "Hiragino Sans GB", Arial, Helvetica, simsun, 宋体;"><span class="pln" style="color: rgb(0, 0, 0);">CRYPTO_cbc128_decrypt</span></span><span style="font-family: "Hiragino Sans GB W3", "Hiragino Sans GB", Arial, Helvetica, simsun, 宋体;"><span class="pun" style="color: rgb(102, 102, 0);">,而它又将</span></span></span></span><span style="font-family: "Hiragino Sans GB W3", "Hiragino Sans GB", Arial, Helvetica, simsun, 宋体;"><strong><span style="color: rgb(255, 0, 0);"><span class="pln" style="color: rgb(0, 0, 0);">AES_encrypt</span><span class="pun" style="color: rgb(102, 102, 0);">作为参数传入</span></span></strong><span class="pun" style="color: rgb(102, 102, 0);">。</span></span></p>
<p style="margin-top: 0px; margin-bottom: 10px; padding-top: 0px; padding-bottom: 0px;"></p><div><span style="font-family: "Hiragino Sans GB W3", "Hiragino Sans GB", Arial, Helvetica, simsun, 宋体; white-space: normal;"><span class="str" style="color: rgb(0, 136, 0);">"crypto/modes/</span></span><span style="font-family: "Hiragino Sans GB W3", "Hiragino Sans GB", Arial, Helvetica, simsun, 宋体;"><span style="white-space: normal;"><span class="str" style="color: rgb(0, 136, 0);">cbc128.c"</span></span></span></div><div><span class="kwd" style="color: rgb(0, 0, 136);">void</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(255, 0, 0);"><span class="pln" style="color: rgb(0, 0, 0);">CRYPTO_cbc128_encrypt</span></span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">const</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">unsigned</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">char</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">*</span><span class="kwd" style="color: rgb(0, 0, 136);">in</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">unsigned</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">char</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">*</span><span class="kwd" style="color: rgb(0, 0, 136);">out</span><span class="pun" style="color: rgb(102, 102, 0);">,</span></div><div><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">size_t</span><span class="pln" style="color: rgb(0, 0, 0);"> len</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">const</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">void</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">*</span><span class="pln" style="color: rgb(0, 0, 0);">key</span><span class="pun" style="color: rgb(102, 102, 0);">,</span></div><div><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">unsigned</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">char</span><span class="pln" style="color: rgb(0, 0, 0);"> ivec</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">16</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> block128_f block</span><span class="pun" style="color: rgb(102, 102, 0);">)</span></div><div><span class="pun" style="color: rgb(102, 102, 0);">{</span><span style="color: rgb(255, 0, 0);"><span class="com" style="color: rgb(136, 0, 0);">//这里的block就是</span><span style="font-family: "Hiragino Sans GB W3", "Hiragino Sans GB", Arial, Helvetica, simsun, 宋体;"><span class="com" style="color: rgb(136, 0, 0);">AES_encrypt</span></span></span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">size_t n;</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">const unsigned char *iv = ivec;</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">assert(in && out && key && ivec);</span></div><div><span class="com" style="color: rgb(136, 0, 0);">#if !defined(OPENSSL_SMALL_FOOTPRINT)</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">if (STRICT_ALIGNMENT &&</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);"> ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">while (len>=16) {</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">for(n=0; n<16; ++n)</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">out[n] = in[n] ^ iv[n];</span><span style="color: rgb(255, 0, 0);"><span class="com" style="color: rgb(136, 0, 0);">//输入与初始化向量进行异或,保存在out</span></span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">(*block)(out, out, key);</span><span style="color: rgb(255, 0, 0);"><span class="com" style="color: rgb(136, 0, 0);">//调用</span><span style="font-family: "Hiragino Sans GB W3", "Hiragino Sans GB", Arial, Helvetica, simsun, 宋体;"><span class="com" style="color: rgb(136, 0, 0);">AES_encrypt进行加密,异或结果out作为加密输入</span></span></span></div><div><span style="color: rgb(255, 0, 0);"><span style="font-family: "Hiragino Sans GB W3", "Hiragino Sans GB", Arial, Helvetica, simsun, 宋体;"><span class="com" style="color: rgb(136, 0, 0);"> //加密输出结果也保存在out里面,</span></span></span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">iv = out;</span><span style="color: rgb(255, 0, 0);"><span class="com" style="color: rgb(136, 0, 0);">//将前一次密文,作为后一次的初始化向量,从而完成加密</span></span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">len -= 16;</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">in += 16;</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">out += 16;</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">}</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">} else {</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">while (len>=16) {</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">for(n=0; n<16; n+=sizeof(size_t))</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">*(size_t*)(out+n) =</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">*(size_t*)(in+n) ^ *(size_t*)(iv+n);</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">(*block)(out, out, key);</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">iv = out;</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">len -= 16;</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">in += 16;</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">out += 16;</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">}</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">}</span></div><div><span class="com" style="color: rgb(136, 0, 0);">#endif</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">while (len) {</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">for(n=0; n<16 && n<len; ++n)</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">out[n] = in[n] ^ iv[n];</span><span style="color: rgb(255, 0, 0);"><span class="com" style="color: rgb(136, 0, 0);">//in和iv异或</span></span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">for(; n<16; ++n)</span><span style="color: rgb(255, 0, 0);"><span class="com" style="color: rgb(136, 0, 0);">//</span><span style="font-family: "Hiragino Sans GB W3", "Hiragino Sans GB", Arial, Helvetica, simsun, 宋体;"><span class="com" style="color: rgb(136, 0, 0);">如果in长度不是16的整数倍</span></span></span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">out[n] = iv[n];</span><span style="color: rgb(255, 0, 0);"><span class="com" style="color: rgb(136, 0, 0);">//最后的out直接用iv初始化,其实也就相当于out与0进行异或</span></span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">(*block)(out, out, key);</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">iv = out;</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">if (len<=16) break;</span><span style="color: rgb(255, 0, 0);"><span class="com" style="color: rgb(136, 0, 0);">//加密结束</span></span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">len -= 16;</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">in += 16;</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">out += 16;</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">}</span></div><div><span class="com" style="color: rgb(136, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">memcpy(ivec,iv,16);</span></div><div><span class="com" style="color: rgb(136, 0, 0);">}</span></div><div><span style="font-family: "Hiragino Sans GB W3", "Hiragino Sans GB", Arial, Helvetica, simsun, 宋体; white-space: normal;"><span class="com" style="color: rgb(136, 0, 0);">//从上面的源码可以看出,cbc本质上和ecb差别不大,唯一区别是将前一次加密结果,与要加密的内容异或。因此,cbc的并行性较差,因为每次都要等待前一次的结果,而ecb则不用,速度较快。其主要区别仍然看文章开头,原理图看参考链接。</span></span></div><p style="margin-top: 0px; margin-bottom: 10px; padding-top: 0px; padding-bottom: 0px;"></p>
调用实例:
- int aes_encrypt(char* in, char* key, char* out)//, int olen)
- {
- if(!in || !key || !out) return 0;
- AES_KEY aes;
- if(AES_set_encrypt_key((unsigned char*)key, 128, &aes) < 0)
- {
- return 0;
- }
- int len=strlen(in)/<span style="font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53;">AES_BLOCK_SIZE*</span><span style="font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53;">AES_BLOCK_SIZE</span><span style="font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53;">, en_len=0;</span><span style="font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53;">
- </span> while(en_len<len)//输入输出字符串够长,并且是AES_BLOCK_SIZE的整数倍,需要严格限制
- {
- AES_encrypt((unsigned char*)in, (unsigned char*)out, &aes);
- in+=AES_BLOCK_SIZE;
- out+=AES_BLOCK_SIZE;
- en_len+=AES_BLOCK_SIZE;
- }
- return 1;
- }
- int aes_decrypt(char* in, char* key, char* out)
- {
- if(!in || !key || !out) return 0;
- AES_KEY aes;
- if(AES_set_decrypt_key((unsigned char*)key, 128, &aes) < 0)
- {
- return 0;
- }
- int len=strlen(in), en_len=0;
- while(en_len<len)
- {
- AES_decrypt((unsigned char*)in, (unsigned char*)out, &aes);
- in+=AES_BLOCK_SIZE;
- out+=AES_BLOCK_SIZE;
- en_len+=AES_BLOCK_SIZE;
- }
- return 1;
- }
- AES_encrypt <pre code_snippet_id="232583" snippet_file_name="blog_20140312_1_226454" name="code" class="cpp" style="color: rgb(55, 42, 24); font-size: 16px; line-height: 28px;">AES_decrypt
- int aes_encrypt(char* in, char* key, char* out)//, int olen)
- {
- if(!in || !key || !out) return 0;
- AES_KEY aes;
- if(AES_set_encrypt_key((unsigned char*)key, 128, &aes) < 0)
- {
- return 0;
- }
- <pre code_snippet_id="232583" snippet_file_name="blog_20140312_1_226454" name="code" class="cpp" style="color: rgb(55, 42, 24); font-size: 16px; line-height: 28px;"> int len=strlen(in)/<span style="font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53;">AES_BLOCK_SIZE*</span><span style="font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53;">AES_BLOCK_SIZE</span><span style="font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53;">, en_len=0;</span>
- char *lptmp = new char[len+1];
- memset(lptmp, '\0', len+1);
- while(en_len<len)//输入输出字符串够长,并且是AES_BLOCK_SIZE的整数倍,需要严格限制
- {
- AES_encrypt((unsigned char*)in, (unsigned char*)lptmp, &aes);
- in+=AES_BLOCK_SIZE;
- <span style="font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53;">lptmp</span><span style="font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53;">+=AES_BLOCK_SIZE;</span>
- en_len+=AES_BLOCK_SIZE;
- <span style="color:#372a18;"> //hex(lptmp) </span><strong><span style="color:#ff0000;">那么就发现第一个数据块加密的结果是对的,后面就错误了,加密后的数据很多是0,查了openssl的</span></strong>
- <strong><span style="color:#ff0000;"> //源代码这个aes这块的加解密是线程安全的,有谁知道原因?</span></strong>
- }
- if(lptmp)
- {
- delete []lptmp;
- lptmp = NULL;
- }
- return 1;
- }
最后给出一个链接,利用openssl的AES接口进行编程。
参考资料: