OpenSSL aes加解密实例+base64编解码

OpenSSL aes加解密简单实例+base64编解码

#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <openssl/aes.h>
#include <stdlib.h>

#define AES_BLOCK_SIZE 16
#define BUF_SIZE 1024
#define CRYPT_USER_KEY "d1ea806ec3c35643"

static const unsigned char en_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static unsigned char de_table[128] = {0};

static void init_de_table()
{
    if (de_table[0] != 0) {
        return;
    }
    memset(de_table, 0xff, sizeof(de_table));
    const unsigned char* p;
    for (p = en_table; *p != 0; p++) {
        de_table[*p] = p - en_table;
    }
    de_table['='] = 0;
}

int get_encode_len(int len)
{
    return (((len/3 + (len%3==0 ? 0:1)) * 4) + 1);
}

int get_decode_len(int len)
{
    return ((len/4)*3 + 1);
}

// base64 编码
int base64_encode(const unsigned char* data, int data_len, char* dst, int dst_len)
{
    if (data == NULL || data_len == 0 || dst == NULL || dst_len == 0) {
        return -1;
    }

    if (dst_len < get_encode_len(data_len)) {
        return -2;
    }

    int mod_len = data_len%3;

    char* dst_tmp = dst;

    int pos = 0;
    for (pos = 0; pos+2 < data_len; pos+=3) {
        *(dst_tmp++) = en_table[data[pos] >> 2];
        *(dst_tmp++) = en_table[((data[pos] & 0x03) << 4) | (data[pos+1] >> 4)];
        *(dst_tmp++) = en_table[((data[pos+1] & 0x0f) << 2) | (data[pos+2] >> 6)];
        *(dst_tmp++) = en_table[data[pos+2] & 0x3f];
    }

    if (mod_len == 2) {
        *(dst_tmp++) = en_table[data[pos] >> 2];
        *(dst_tmp++) = en_table[((data[pos] & 0x03) << 4) | (data[pos+1] >> 4)];
        *(dst_tmp++) = en_table[((data[pos+1] & 0x0f) << 2)];
        *(dst_tmp++) = '=';
    }
    else if (mod_len == 1) {
        *(dst_tmp++) = en_table[data[pos] >> 2];
        *(dst_tmp++) = en_table[((data[pos] & 0x03) << 4)];
        *(dst_tmp++) = '=';
        *(dst_tmp++) = '=';
    }

    *dst_tmp = 0;

    return (dst_tmp - dst);
}

// base64 解码
int base64_decode(const unsigned char* data, int data_len, char* dst, int dst_len)
{
    if (data == NULL || data_len < 4 || dst == NULL || dst_len == 0) {
        return -1;
    }

    if (dst_len < get_decode_len(data_len)) {
        return -2;
    }

    init_de_table();

    char* dst_tmp = dst;
    int pos;
    for (pos = 0; pos < data_len; pos+=4) {
        if (de_table[data[pos]]==0xff || de_table[data[pos+1]]==0xff 
            || de_table[data[pos+2]]==0xff || de_table[data[pos+3]]==0xff)
        {
            return -3;
        }
        *(dst_tmp++) = (de_table[data[pos]]<<2) | (de_table[data[pos+1]]>>4)&0x3;
        *(dst_tmp++) = (de_table[data[pos+1]]<<4) | (de_table[data[pos+2]]>>2)&0x0f;
        *(dst_tmp++) = (de_table[data[pos+2]]<<6) | (de_table[data[pos+3]])&0x3f;
    }

    while (*(dst_tmp-1) == 0) {
        dst_tmp--;
    }

    *dst_tmp = 0;

    return (dst_tmp - dst);
}

// 根据数据字节数 获取加密字节数
int get_crypt_size(int data_len)
{
    return ((data_len/AES_BLOCK_SIZE)+((data_len%AES_BLOCK_SIZE) == 0 ? 0:1))*AES_BLOCK_SIZE;
}

// 加密
int aes_encrypt(char* in, char* key, char* out)//, int olen)  
{
    if(NULL == in || NULL == key || NULL == out)
        return -1;
    
    AES_KEY aes;
    if(AES_set_encrypt_key((unsigned char*)key, 128, &aes) < 0)
    {
        return -2;
    }
    
    int len=strlen(in);
    int 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 get_crypt_size(len);
}

// 解密
int aes_decrypt(char* in, int in_len, char* key, char* out)
{
    if(NULL == in || NULL == key || NULL == out)
        return -1;
    
    AES_KEY aes;
    if(AES_set_decrypt_key((unsigned char*)key, 128, &aes) < 0)
    {
        return -2;
    }
    
    int en_len=0;
    while(en_len<in_len)
    {
        AES_decrypt((unsigned char*)in, (unsigned char*)out, &aes);
        in+=AES_BLOCK_SIZE;
        out+=AES_BLOCK_SIZE;
        en_len+=AES_BLOCK_SIZE;
    }
    
    return 0;
}

int main(int argc, char* argv[])
{
    if (argc < 2)
        return -1;

    printf("src: %s\n", argv[1]);
    char in[BUF_SIZE] = {0};
    memcpy(in, argv[1], strlen(argv[1]));
    
    
    char aes_en[BUF_SIZE] = {0};
    int aes_en_len = aes_encrypt(in, CRYPT_USER_KEY, aes_en); // aes-128 加密
    if (aes_en_len < 0)
    {
        printf("aes_encrypt error ret: %d\n", aes_en_len);
        return -1;
    }
    int i=0;
    printf("aes_en: {");
    for(i=0; i<aes_en_len; i++) printf(" %d",aes_en[i]);
    printf(" } aes_en_len: %d\n", aes_en_len);
    
    
    char base64_en[BUF_SIZE] = {0};
    int base64_en_len = base64_encode(aes_en, aes_en_len, base64_en, BUF_SIZE); // base64 编码
    if (base64_en_len < 0)
    {
        printf("base64_encode error ret: %d\n", base64_en_len);
        return -1;
    }
    printf("base64_en_len: %d base64_en: %s\n", base64_en_len, base64_en);
    
    
    char base64_de[BUF_SIZE] = {0};
    int base64_de_len = base64_decode(base64_en, base64_en_len, base64_de, BUF_SIZE); // base64 解码
    if (base64_de_len < 0)
    {
        printf("base64_encode error ret: %d\n", base64_de_len);
        return -1;
    }
    printf("base64_de: {");
    for(i=0; i<base64_de_len; i++) printf(" %d",base64_de[i]);
    printf(" } base64_de_len: %d\n", base64_de_len);
    
    char aes_de[BUF_SIZE] = {0};
    int aes_de_len = aes_decrypt(base64_de, base64_de_len, CRYPT_USER_KEY, aes_de); // aes-128 解密
    if (aes_de_len < 0)
    {
        printf("aes_encrypt error ret: %d\n", aes_de_len);
        return -1;
    }
    printf("aes_de_len: %d aes_en: %s\n", strlen(aes_de), aes_de);
    
    return 0;
}

 

编译时要 libcrypto.so

posted @ 2019-11-08 12:31  aoong  阅读(1014)  评论(0编辑  收藏  举报