c语言通过openssl aes对称加解密和base64编解码将密码存储成密文

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/FlayHigherGT/article/details/84636086

今天遇到这样一个问题,将客户端中的一个密码存储到文件中以供下次使用,但是存储的密码不能直接存储明文,需要进行加密处理,再三考虑之后,这个加密的过程需要双向的可逆的过程,MD5等方式是不适用的,因为记住密码意味着下次我还需要还原这个密码进行使用,所以最后选择了openssl的aes算法,然而aes可行然而用遇到另外一个问题,aes编码字符串之后是乱码,只能用16进制数来显示,这样我使用的glib的keyfile parser配置文件接口又读不起来乱码,所有中间又加了一层,base64编解码,大概流程如下:

密码字符串->openssl aes编码->base64编码->存文件----------读文件->base64解码->openssl aes解码->得到原始字符串

下面是代码,具体的分析写在注释上:

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "openssl/pem.h"
#include "openssl/bio.h"
#include "openssl/evp.h"
#include "openssl/aes.h"

/*这个是你自己写的一个十六字节的秘钥,aes加密解密都用这同一个*/
unsigned char key[AES_BLOCK_SIZE] = "123456789abcdef";

#define AES_BITS 10240
#define MSG_LEN 10240

/**********************************************************
函数名:getlen
参数:char *result        --字符串地址
返回值:int                --字符串长度
说明:                    --获取字符串长度
***********************************************************/
int getlen(char *result) {
    int i = 0;
    while (result[i] != '\0') {
        i++;
    }
    return i;
}

/**********************************************************
函数名:aes_encrypt
参数:const char* str_in        --输入字符
参数:unsigned char* key        --key
参数:unsigned char* out        --输出字符
返回值:int                      --0失败  1成功
说明:加密
***********************************************************/
int aes_encrypt(char* str_in, char* out)
{
    if (!str_in || !key || !out) return 0;

    //加密的初始化向量
    unsigned char iv[AES_BLOCK_SIZE];
    //这个也是加密解密同一个确保十六字节里面的内容加密解密一样就ok

    for (int i = 0; i < 16; ++i)
        iv[i] = 32 + i;

    //通过自己的秘钥获得一个aes秘钥以供下面加密使用,128表示16字节
    AES_KEY aes;
    if (AES_set_encrypt_key((unsigned char*)key, 128, &aes) < 0)
    {
        return 0;
    }

    int len = getlen(str_in);
    //这边是加密接口,使用之前获得的aes秘钥
    AES_cbc_encrypt((unsigned char*)str_in, (unsigned char*)out, len, &aes, iv, AES_ENCRYPT);
    return 1;
}

/**********************************************************
函数名:aes_decrypt
参数:const char* str_in        --输入
参数:unsigned char* key        --key
参数:unsigned char* out        --输出
返回值:int                  --0失败  1成功
说明:                --解密
***********************************************************/
int aes_decrypt(char* str_in, char* out)
{
    if (!str_in || !key || !out)
        return 0;

    unsigned char iv[AES_BLOCK_SIZE];
    //这个也是加密解密同一个确保十六字节里面的内容加密解密一样就ok
    for (int i = 0; i < 16; ++i)
        iv[i] = 32 + i;

    //通过自己的秘钥获得一个aes秘钥以供下面解密使用,128表示16字节
    AES_KEY aes;
    if (AES_set_decrypt_key((unsigned char*)key, 128, &aes) < 0)
    {
        return 0;
    }

    int len = getlen(str_in);
    //这边是解密接口,使用之前获得的aes秘钥
    AES_cbc_encrypt((unsigned char*)str_in, (unsigned char*)out, len, &aes, iv, AES_DECRYPT);
    return 1;
}

//base64加密
int base64_encode(char *in_str, int in_len, char *out_str)
{
    BIO *b64, *bio;
    BUF_MEM *bptr = NULL;
    size_t size = 0;

    if (in_str == NULL || out_str == NULL)
        return -1;

    b64 = BIO_new(BIO_f_base64());
    bio = BIO_new(BIO_s_mem());
    bio = BIO_push(b64, bio);

    BIO_write(bio, in_str, in_len);
    BIO_flush(bio);

    BIO_get_mem_ptr(bio, &bptr);
    memcpy(out_str, bptr->data, bptr->length);
    out_str[bptr->length] = '\0';
    size = bptr->length;

    BIO_free_all(bio);
    return size;
}

//base64解密
int base64_decode(char *in_str, int in_len, char *out_str)
{
    BIO *b64, *bio;
    BUF_MEM *bptr = NULL;
    int counts;
    int size = 0;

    if (in_str == NULL || out_str == NULL)
        return -1;

    b64 = BIO_new(BIO_f_base64());
    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);

    bio = BIO_new_mem_buf(in_str, in_len);
    bio = BIO_push(b64, bio);

    size = BIO_read(bio, out_str, in_len);
    out_str[size] = '\0';

    BIO_free_all(bio);
    return size;
}

int main(int argc, char *argv[])
{
    if (argc < 2)
    {
        printf("please input origin str\n");
        return 0;
    } else
    {
        printf("origin-str:%s\n", argv[1]);
    }

    //aes加密
    char aes_encode_out[30] = {0};
    aes_encrypt(argv[1], aes_encode_out);
    printf("aes_encode_out:%s\n", aes_encode_out);

    //base64加密
    char base64_encode_out[1024] = {0};
    base64_encode(aes_encode_out, strlen(aes_encode_out), base64_encode_out);
    printf("base64_encode_out:%s\n", base64_encode_out);

    //base64解密
    char base64_decode_out[1024] = {0};
    base64_decode(base64_encode_out, strlen(base64_encode_out), base64_decode_out);
    printf("base64_decode_out:%s\n", base64_decode_out);

    //aes解密
    char aes_decode_out[30] = {0};
    aes_decrypt(base64_decode_out, aes_decode_out);
    printf("aes_decode_out:%s\n", aes_decode_out);
    return 0;
}

编译运行过程:

猜你喜欢

转载自blog.csdn.net/FlayHigherGT/article/details/84636086