const EVP_CIPHER *cipher; unsigned char key[24],iv[8],in[100],out[108],de[100]; int i,len,inl,outl,total=0; EVP_CIPHER_CTX ctx; //此init做的仅是将ctx内存 memset为0 EVP_CIPHER_CTX_init(&ctx); cipher = EVP_aes_128_ecb(); //原型为int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl, const unsigned char *key, const unsigned char *iv) //另外对于ecb电子密码本模式来说,各分组独立加解密,前后没有关系,也用不着iv EVP_EncryptInit_ex(&ctx, cipher, NULL, key, iv); inl=50; len=0; EVP_EncryptUpdate(&ctx,out+len,&outl,in,inl); //这个EVP_EncryptUpdate的实现实际就是将in按照inl的长度去加密,实现会取得该cipher的块大小(对aes_128来说是16字节)并将block-size的整数倍去加密。如果输入为50字节,则此处仅加密48字节,outl也为48字节。输入in中的最后两字节拷贝到ctx->buf缓存起来。 //对于inl为block_size整数倍的情形,且ctx->buf并没有以前遗留的数据时则直接加解密操作,省去很多后续工作。 len+=outl; EVP_EncryptUpdate(&ctx,out+len,&outl,in+50,inl); //同样的函数,但是先检查ctx->buf中有数据,则将in拷贝到buf之后,并进行同样的加解密操作(调用该cipher的do_cipher实现)。 len+=outl; EVP_EncryptFinal_ex(&ctx,out+len,&outl); //对于如本例所述,第一次除了了48字节余两字节,第二次处理了第一次余下的2字节及46字节,余下了输入100字节中的最后4字节。此处进行处理。如果不支持pading,且还有数据的话就出错,否则,将block_size-待处理字节数个数个字节设置为此个数的值,如block_size=16,数据长度为4,则将后面的12字节设置为16-4=12,补齐为一个分组后加密 对于前面为整分组时,如输入数据为16字节,最后再调用此Final时,不过是对16个0进行加密,此密文不用即可,也根本用不着调一下这Final。 len+=outl; EVP_CIPHER_CTX_cleanup(&ctx); //ctx上下文清理
综上仅对16及16字节倍数长度的输入加密时,只要Update就足够了,非要用Final的时候记得输出缓冲区大一点,超过输入长度的输出不用就行...