c/c++密码存储加密例子

在编写各种客户端的过程中需要在配置文件中存储密码,但是密码肯定需要加密,当读取配置文件密码时又需要解密,下面代码就通过openssl库在linux下实现了这两个加解密的功能。

之前是使用《c语言通过openssl aes对称加解密和base64编解码将密码存储成密文》

c语言通过openssl aes对称加解密和base64编解码将密码存储成密文_GT19930910的博客-CSDN博客

这篇文章来实现的,后来发现这个加解密过程对于有些字符串来说有问题,会导致加解密之后出来的字符串和原字符串不一样,很有可能是因为编码之后16进制字符中有特殊字符所以导致base64编解码失败,所以下面给大家又展现一版现在咱们项目里面一直在用的接口,完成编解码功能。


/*  Created by verycloud on 2020/09/18.
    Copyright © 2019 verycloud. All rights reserved.

    build in cmdline
    gcc -g -O0 main.c -lssl -lcrypto
*/
#include <openssl/evp.h>
#include <openssl/md5.h>
#include <string.h>
#include <stdio.h>
/*
 *  @parme in  str end by '\0'
 *  @parme out buf size >= 33
 */
void make_md5(const char* in,char* out)
{
    int inSize = (int)strlen(in);

    unsigned char buf[16];
    MD5((const unsigned char*)in, inSize, (unsigned char*)buf);

    char tmp[3] = {0};
    for (int i = 0; i < 16; i++) {
        sprintf(tmp, "%02x", (int)buf[i]);
        strcat(out,tmp);
    }
}

void make_base64_2K(char s[])
{
    unsigned char buf[2048];
    int len = EVP_EncodeBlock((unsigned char*)buf, (const unsigned char*)s, strlen(s));
    strncpy(s, buf, len);
}

void m_append(char s[], char tmp[], int len)
{
    if(s[0] == 0)
    {
        strncpy(s, tmp, len);
    }else
    {
        strncat(s, tmp, len);
    }
}

int string_find(char tmp[], char c)
{
    int i;
    for(i=0; i<strlen(tmp); i++)
    {
        if(tmp[i] == c)
        {
            break;
        }
    }
    return i;
}

char* vcd_encode_crypto(const char* in, char* out)
{
    int i, j, k = 0;

    char str[1024] = {0};
    strncpy(str, in, 1024);

    const char* public_key = "!Knowledge@#is#@power~@";
    const char* lockstream = "st=lDEFABCNOPyzghi_jQRST-UwxkVWXYZabcdefIJK67nopqr89LMmGH012345uv";

    int strLen  = (int)strlen(str);
    int lockLen = (int)strlen(lockstream);

    char randomLock = str[strLen-1];
    int lockCount = (int)(strchr(lockstream, randomLock) - lockstream);

    // public_key + randomLock + '\0'
    int keyLen = (int)strlen(public_key) + 1 + 1;
    char* keyBuf = malloc(keyLen);
    sprintf(keyBuf, "%s%c", public_key, randomLock);

    char password[33] = {0};
    make_md5(keyBuf, password);

    make_base64_2K(str);

    char tmpStream[200] = {0};
    for(i=0,j=0,k=0; i<strlen(str); i++)
    {
        k = (k == strlen(password)) ? 0 : k;
        j = (lockCount + (int)password[k] + string_find(lockstream, str[i])) % lockLen;
        tmpStream[strlen(tmpStream)] = lockstream[j];
        k++;
    }
    tmpStream[strlen(tmpStream)] = randomLock;

    strcpy(out, tmpStream);
    free(keyBuf);
    return out;
}

char* vcd_decode_crypto(const char* str, char* out){

    if (!str || !out) return NULL;

    const char* public_key = "!Knowledge@#is#@power~@";
    const char* lockstream = "st=lDEFABCNOPyzghi_jQRST-UwxkVWXYZabcdefIJK67nopqr89LMmGH012345uv";

    int strLen  = (int)strlen(str);
    int lockLen = (int)strlen(lockstream);

    char randomLock = str[strLen-1];
    int lockCount = (int)(strchr(lockstream, randomLock) - lockstream);

    // public_key + randomLock + '\0'
    int keyLen = (int)strlen(public_key) + 1 + 1;
    char* keyBuf = malloc(keyLen);
    sprintf(keyBuf, "%s%c", public_key, randomLock);

    char password[33] = {0};
    make_md5(keyBuf, password);
    //printf("make_md5: %s\n", password);

    int k = 0;
    char* beforeBase64 = malloc(strLen-1);
    for(int i = 0; i < strLen-1;i++) {
        k = k == strlen(password) ? 0 : k;

        int j = (int)(strchr(lockstream,str[i])-lockstream) - lockCount - (int)password[k];
        while(j < 0)
            j = j + lockLen;
        beforeBase64[i] = lockstream[j];
        k++;
    }

    EVP_DecodeBlock((unsigned char *)out, (unsigned char *)beforeBase64, strLen-1);

    free(keyBuf);
    free(beforeBase64);
    return out;
}

int main(int argc, char** argv)
{
    if (argc < 2) {
        printf("usage: ./a.out test_string\n");
        return 0;
    }
    printf("test_string:%s\n", argv[1]);
    char encode_out[1024] = {0};
    vcd_encode_crypto(argv[1], encode_out);
    printf("encode out: %s\n", encode_out);
    char decode_out[1024] = {0};
    vcd_decode_crypto(encode_out, decode_out);
    printf("decode out: %s\n", decode_out);
    return 0;
}

 最后欢迎大家一起学习一些其他c/c++技术:

(21条消息) 收集一些c/c++技术_GT19930910的博客-CSDN博客

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值