APP安全(四)-结合MD5、DES生成一个AES Secret Key

一、 前言

签名讲过使用我们使用AES加密算法与服务端进行数据加解密交互,对AES来说,secret key,如果我们把key硬编码在代码里面,被逆向后也很容易找到对应的key,隐藏我们需要设计一套算法来保证key是动态生成,不是硬编码在代码里。这里我们使用MD5以及DES来增加算法的破解难度,其中的核心是MD5摘要算法,它的出现保证了secret key的产生不是唯一的。

二、具体实现方案

1)MD5介绍

参考百度百科:https://baike.baidu.com/item/MD5/212708?fr=aladdin

MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。具有以下特点:

  1. 压缩性:任意长度的数据,算出的MD5值长度都是固定的。
  2. 容易计算:从原数据计算出MD5值很容易。
  3. 抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
  4. 强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
MD5作用:

把一个任意长度的字节串变换成一定长的十六进制数字串,只要原始内容不变,产生的摘要内容就不会变。

结合MD5生成一个AES Secret Key

secrete key 的生成原理,对任意一个字符进行MD5,取出MD值,与对应长度key进行位运算,保证产生的index在目标数据的长度范围内,再根据index取出值,从而生成secret key。具体实现代码如下:

#include <string>
#include "openssl/md5.h"
using namespace std;
const char strKey[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

string createKey(const string &key){
    unsigned char md[MD5_DIGEST_LENGTH];
    const char *tem = key.c_str();
    MD5((const unsigned char*)tem, key.length(),(unsigned char*)&md);
    int len = MD5_DIGEST_LENGTH;
    //key length = 16
    char keyChar[len];
    int index = 0;
    for(int i = 0; i < len; i++){
        keyChar[index++] = strKey[(md[i] >> 2) & 0x3D];
    }
    string rs(keyChar,len);
    return rs;
}

1)结合DES

上述方式已经生成了AES的secret key,但是为了增加破解难度,再次结合DES算法,解密一个数据,作为生成key的原始内容。这里DES的实现和AES的实现都相似,采用CBC/PKCS5Padding填充模式,具体实现参考如下代码:

#include "openssl/des.h"

/***
* src:明文
* srcLen:明文长度
* key:密钥
* keyLen:密钥长度
* outLen:密文长度
* 返回值:密文 需要free
*
*/
unsigned char *des_encrypt(unsigned char *src, int srcLen, unsigned char *aesKey, int keyLen, int *outLen)
{
    int aes_block_size = 8;
    int blockCount = 0;
    int quotient = srcLen / aes_block_size;
    int mod = srcLen % aes_block_size;
    blockCount = quotient + 1;
    int allLength = blockCount * aes_block_size;

    int padding = aes_block_size - mod;
    char *in = (char *)malloc(allLength);
    memset(in, padding, allLength);
    memcpy(in, src, srcLen);

    DES_cblock  key;
    DES_key_schedule key_schedule;
    memcpy(key,aesKey,keyLen);
    DES_set_key_unchecked(&key, &key_schedule);

   //IV
    DES_cblock ivec;
    memcpy(ivec, aesKey, keyLen);
    //out
    char *out = (char *)malloc(allLength);
    memset(out, 0x00, allLength);
    *outLen = allLength;
    DES_ncbc_encrypt((unsigned char*)in, (unsigned char*)out, allLength, &key_schedule, &ivec, DES_ENCRYPT);
    free(in);
    return (unsigned char*)out;
}


/**
* decrypt
* src:密文
* srcLen:密文长度
* key:密钥
* keyLen:密钥长度
* outLen:明文长度
* 返回值: 明文 需要free
*/
unsigned char *des_decrypt(unsigned char *src, int srcLen, unsigned char *aesKey, int keyLen, int *outLen)
{

    DES_cblock key;
    DES_key_schedule key_schedule;
    memcpy(key,aesKey,keyLen);
    DES_set_key_unchecked(&key, &key_schedule);
    unsigned char *tmp = (unsigned char *)malloc(srcLen);
    memset(tmp,0,srcLen);
    //IV
    DES_cblock iv;
    memcpy(iv, aesKey, keyLen);
    DES_ncbc_encrypt((const unsigned char *)src, tmp, srcLen, &key_schedule, &iv, DES_DECRYPT);

    int unpadding = tmp[srcLen - 1];
    *outLen = srcLen - unpadding;
    char *out = (char *)malloc(*outLen);
    memcpy(out, tmp, *outLen);

    free(tmp);
    return (unsigned char*)out;
}

三、总结

  1. 介绍了MD5的特性
  2. 如何结合MD5生成AES Secret Key
  3. DES的实现,对于这两者的结合使用,将在后面的章节介绍

项目github地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值