openssl的AES128加密總結

AES加密基本原理:
這裏寫圖片描述
1.把明文按照128bit拆分成若干個明文塊。
2.按照選擇的填充方式來填充最後一個明文塊。
3.每一個明文塊利用AES加密器和密鑰,加密成密文塊。
4.拼接所有的密文塊,成爲最終的密文結果。

AES支持三種長度的密鑰:
128位,192位,256位

填充方式:
NoPadding:
不做任何填充,但是要求明文必須是16字節的整數倍。

PKCS5Padding(默認):
如果明文塊少於16個字節(128bit),在明文塊末尾補足相應數量的字符,且每個字節的值等於缺少的字符數。

AES工作模式:
AES的工作模式,體現在把明文塊加密成密文塊的處理過程中。AES加密算法提供了五種不同的工作模式:
CBC、ECB、CTR、CFB、OFB

Linux C實現aes128_cbc_pkcs5pading:

#include <openssl/ssl.h> 
#include <openssl/aes.h> 
#define BLOCK_SIZE 16

/* sz_in_buff 輸入字符串
*  key 爲密鑰
*  iv爲偏移量
*  sz_out_buff 加密輸出字符串
*/
int aes_encrypt_pkcs5pading(unsigned char *sz_in_buff, int sz_in_len, unsigned char *key,unsigned char *iv, unsigned char *sz_out_buff)
{
    EVP_CIPHER_CTX ctx;

    int len=0,isSuccess = 0;
    unsigned char in[BLOCK_SIZE];  
    int outl = 0;   
        int outl_total = 0; 

    EVP_CIPHER_CTX_init(&ctx);  

    EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);

    while(sz_in_len >=BLOCK_SIZE)
    {
        memcpy(in, sz_in_buff, BLOCK_SIZE);  
            sz_in_len -= BLOCK_SIZE;  
            sz_in_buff += BLOCK_SIZE;  
        isSuccess = EVP_EncryptUpdate(&ctx, sz_out_buff + outl_total, &outl, in, BLOCK_SIZE);  
            if(!isSuccess)  
            {  
                    printf("EVP_EncryptUpdate() failed");  
                    EVP_CIPHER_CTX_cleanup(&ctx);  
                    return 0;  
            }  
            outl_total += outl;  
    }

     if(sz_in_len > 0)  
        {  
            memcpy(in, sz_in_buff, sz_in_len); 
            isSuccess = EVP_EncryptUpdate(&ctx,sz_out_buff + outl_total, &outl, in, sz_in_len);  
            outl_total += outl;  

        isSuccess = EVP_EncryptFinal_ex(&ctx,sz_out_buff + outl_total,&outl);  
            if(!isSuccess)  
            {  
                printf("EVP_EncryptFinal_ex() failed");  
                EVP_CIPHER_CTX_cleanup(&ctx);  
                return 0;  
            }  
            outl_total += outl;  
        }     

        EVP_CIPHER_CTX_cleanup(&ctx); 
    return outl_total;
}

/* sz_in_buff 輸入解密字符串
*  key 爲密鑰
*  iv爲偏移量
*  sz_out_buff 輸出解密後字符串
*/
int aes_decrypt_pkcs5pading(unsigned char *sz_in_buff, int sz_in_length, unsigned char *key,unsigned char *iv, unsigned char *sz_out_buff)
{
    unsigned char in[BLOCK_SIZE];  
        int outl = 0;  
        int outl_total = 0;  
        int isSuccess;  

        EVP_CIPHER_CTX ctx;     

    //初始化ctx,加密算法初始化  
        EVP_CIPHER_CTX_init(&ctx);  
        isSuccess = EVP_DecryptInit_ex(&ctx,EVP_aes_128_cbc(),NULL,key,iv);  
    if(!isSuccess)  
        {  
            printf("EVP_DecryptInit_ex() failed");  
            EVP_CIPHER_CTX_cleanup(&ctx);  
            return 0;  
        }  

    //解密數據  
        while(sz_in_length >BLOCK_SIZE)  
        {  
            memcpy(in, sz_in_buff, BLOCK_SIZE);  
            sz_in_length -= BLOCK_SIZE;  
            sz_in_buff += BLOCK_SIZE;  

            isSuccess = EVP_DecryptUpdate(&ctx, sz_out_buff + outl_total, &outl, in, BLOCK_SIZE);  
            if(!isSuccess)  
            {  
                    printf("EVP_DecryptUpdate() failed");  
                    EVP_CIPHER_CTX_cleanup(&ctx);  
                    return 0;  
            }  
            outl_total += outl;  
        }


    if(sz_in_length > 0)  
        {  
            memcpy(in, sz_in_buff, sz_in_length);  
            isSuccess = EVP_DecryptUpdate(&ctx, sz_out_buff + outl_total, &outl, in, sz_in_length);  
            outl_total += outl;  
        } 

    /*解密數據塊不爲16整數倍時執行 */
     if(sz_in_length % BLOCK_SIZE != 0)  
        {  
            isSuccess = EVP_DecryptFinal_ex(&ctx, sz_out_buff + outl_total, &outl);  
            if(!isSuccess)  
            {  
                printf("EVP_DecryptFinal_ex() failed\n");  
                    EVP_CIPHER_CTX_cleanup(&ctx);  
                    return 0;  
            }  
            outl_total += outl;  
        }  

        EVP_CIPHER_CTX_cleanup(&ctx);  
        return outl_total;  
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章