首先要了解AES加密是什么,以及几种加密模式的区别。之后才是编程。具体的编程案例,在下面的链接。
openssl之aes加密(AES_cbc_encrypt 与 AES_encrypt 的编程案例)
AES加密算法 - 加密模式
openssl提供的aes加密接口
" crypto/aes/ aes_ecb.c"void AES_ecb_encrypt ( const unsigned char * in , unsigned char * out ,const AES_KEY * key , const int enc ) {assert ( in && out && key );assert (( AES_ENCRYPT == enc )||( AES_DECRYPT == enc ));if ( AES_ENCRYPT == enc )AES_encrypt ( in , out , key );elseAES_decrypt ( in , out , key );}从这里可以看出,ecb方式的加密,是由AES_encrypt接口实现的。
"crypto/aes/aes_cbc.c"void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len, const AES_KEY *key, unsigned char *ivec, const int enc) { if (enc) CRYPTO_cbc128_encrypt(in,out,len,key,ivec,(block128_f)AES_encrypt); else CRYPTO_cbc128_decrypt(in,out,len,key,ivec,(block128_f)AES_decrypt); }
从这里看出,cbc加密方式,调用接口CRYPTO_cbc128_decrypt,而它又将AES_encrypt作为参数传入。
"crypto/modes/ cbc128.c"void CRYPTO_cbc128_encrypt ( const unsigned char * in , unsigned char * out ,size_t len , const void * key ,unsigned char ivec [ 16 ], block128_f block ){ //这里的block就是AES_encryptsize_t n;const unsigned char *iv = ivec;assert(in && out && key && ivec);#if !defined(OPENSSL_SMALL_FOOTPRINT)if (STRICT_ALIGNMENT &&((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {while (len>=16) {for(n=0; n<16; ++n)out[n] = in[n] ^ iv[n]; //输入与初始化向量进行异或,保存在out(*block)(out, out, key); //调用AES_encrypt进行加密,异或结果out作为加密输入//加密输出结果也保存在out里面,iv = out; //将前一次密文,作为后一次的初始化向量,从而完成加密len -= 16;in += 16;out += 16;}} else {while (len>=16) {for(n=0; n<16; n+=sizeof(size_t))*(size_t*)(out+n) =*(size_t*)(in+n) ^ *(size_t*)(iv+n);(*block)(out, out, key);iv = out;len -= 16;in += 16;out += 16;}}#endifwhile (len) {for(n=0; n<16 && n<len; ++n)out[n] = in[n] ^ iv[n]; //in和iv异或for(; n<16; ++n) //如果in长度不是16的整数倍out[n] = iv[n]; //最后的out直接用iv初始化,其实也就相当于out与0进行异或(*block)(out, out, key);iv = out;if (len<=16) break; //加密结束len -= 16;in += 16;out += 16;}memcpy(ivec,iv,16);}//从上面的源码可以看出,cbc本质上和ecb差别不大,唯一区别是将前一次加密结果,与要加密的内容异或。因此,cbc的并行性较差,因为每次都要等待前一次的结果,而ecb则不用,速度较快。其主要区别仍然看文章开头,原理图看参考链接。
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), en_len=0; 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; }