C++ lua 交互的 AES加密

背景:

當前開發中,lua中有需要用到aes加密的需求,底層c++是有aes模塊的,但是程序一直沒有用到,我修改了一番。兩點:加密,解密

 

梳理流程:

加密:字符串輸入,祕鑰輸入,16的倍數不足的補N(N爲不足的位數,例:12個字符串,缺4個,後面4個全部補4),AES加密,加密完成,base64再加密,輸出

解密:密碼輸入,祕鑰輸入,base64解密,16的倍數不足的補N(N爲不足的位數,例:12個字符串,缺4個,後面4個全部補4),解密完成,處理解密後字符串中的N(從尾部開始,等於N的字符串,全部刪除),輸出

 

代碼邏輯:

aes.cpp(源代碼)

int AES_ECB_Cipher::encode(const unsigned char* src, uint32_t src_len, unsigned char* dest, uint32_t& len)
{

    // check input null pointer
    if (nullptr == src)
    {
        return -1;
    }
    // make sure dest buff is larger than src buff
    if(len < src_len)
    {
        return -1;
    }
    
    unsigned char encode_buf[1024];
	memset(encode_buf, 0, sizeof(encode_buf));
    memcpy(encode_buf, src, src_len);
    uint32_t encode_buf_size = src_len;
    
    // input been padded well with pkcs5padding
    uint8_t pading_size = AES_ECB_Cipher::KEYLEN - encode_buf_size % AES_ECB_Cipher::KEYLEN;
    // PKCS5Padding rules: ²¹(16-len)¸ö(16-len)
    for (uint8_t pading = 0; pading < pading_size; pading++)
    {
        encode_buf[encode_buf_size + pading] = pading_size;
    }
    encode_buf_size += pading_size;
    
    uint32_t round  = encode_buf_size / AES_ECB_Cipher::KEYLEN;
    const unsigned char * iv = mKey;
    for (uint32_t i = 0; i < round; ++i)
    {
        AES128_ECB_encrypt(encode_buf + i * AES_ECB_Cipher::KEYLEN, dest + i * AES_ECB_Cipher::KEYLEN);
        if (use_cbc)
        {
            for (int j = 0; j < AES_ECB_Cipher::KEYLEN; ++j)
            {
                (dest + i * AES_ECB_Cipher::KEYLEN)[j] ^= iv[j];
            }
            iv = encode_buf + i * AES_ECB_Cipher::KEYLEN;
        }
    }
    
    len = encode_buf_size;
    if (len < 0 || len <= src_len)
    {
        return -1;
    }
    dest[len] = 0;
    return 0;
}

int AES_ECB_Cipher::decode(const unsigned char* src, uint32_t src_len, unsigned char* dest, uint32_t& len)
{
    // check input null pointer
    if (nullptr == src)
    {
        return -1;
    }
    // make sure dest buff is larger than src buff
    if(len < src_len)
    {
        return -1;
    }

	unsigned char encode_buf[1024];
	memset(encode_buf, 0, sizeof(encode_buf));
	memcpy(encode_buf, src, src_len);
	uint8_t pading_size = src_len % AES_ECB_Cipher::KEYLEN;
	for (uint8_t pading = 0; pading < pading_size; pading++)
	{
		encode_buf[src_len + pading] = pading_size;
	}
	src_len += pading_size;

    // assume input has been padded well with pkcs5padding
    if (src_len % AES_ECB_Cipher::KEYLEN != 0)
    {
        return -1;
    }
    uint32_t round  = src_len / AES_ECB_Cipher::KEYLEN;
    const unsigned char * iv = mKey;
    for (uint32_t i = 0; i < round; ++i)
    {
        AES128_ECB_decrypt(encode_buf + i * AES_ECB_Cipher::KEYLEN, dest + i * AES_ECB_Cipher::KEYLEN);
        if (use_cbc)
        {
            for (int j = 0; j < AES_ECB_Cipher::KEYLEN; ++j)
            {
                (dest + i * AES_ECB_Cipher::KEYLEN)[j] ^= iv[j];
            }
            iv = encode_buf + i * AES_ECB_Cipher::KEYLEN;
        }
    }
    // unpad with pkcs5, remove unused charactors
    uint8_t lastASIIC = (uint8_t)dest[src_len - 1];
	for (int i = src_len - 1; i >= src_len - lastASIIC; i--)
	{
		if (dest[i] != lastASIIC)
		{
			return -1;
		}
		else
		{
			dest[i] = 0;
		}
	}
    return 0;
}

 

 

lua_aes.cpp(c++和lua交互的代碼)

int lua_to_aes_EncryptData(lua_State *L)
{
    char *inbuf = (char*)luaL_checkstring(L, 1);
    if (inbuf == nullptr)
    {
        return 0;
    }
    
    char* key = (char*)luaL_checkstring(L, 2);
    if (key == nullptr)
    {
        return 0;
    }
    
    AES_ECB_Cipher aes((unsigned char*)key);
    char out[1024]={0};
    uint32_t dlen = 1024;
    aes.encode((unsigned char*)inbuf,strlen(inbuf),(unsigned char*)out,dlen);
	
	char* out1 = nullptr;
	int dlen1 = cocos2d::base64Encode((unsigned char*)out, (unsigned int)dlen, &out1);
    lua_pushlstring(L,(char*)out1, dlen1);
    
    return 1;
}

int lua_to_aes_DecryptData(lua_State *L)
{
    char *inbuf = (char*)luaL_checkstring(L, 1);
    if (inbuf == nullptr)
    {
        return 0;
    }

    char* key = (char*)luaL_checkstring(L, 2);
    if (key == nullptr)
    {
        return 0;
    }
	unsigned char* outbuf1 = nullptr;
	int dlen1 = cocos2d::base64Decode((unsigned char*)inbuf, strlen(inbuf), &outbuf1);

	AES_ECB_Cipher aes((unsigned char*)key);
	char out[1024] = { 0 };
	uint32_t dlen = 1024;
	aes.decode((unsigned char*)outbuf1, dlen1, (unsigned char*)out, dlen);
    lua_pushlstring(L,(char*)out,sizeof(out));
    
    return 1;
}

 

main.lua(lua中如何使用)

加密:local postdata = aes.encode("123456","aaaa")

解密:local postdata1= aes.decode(postdata ,"aaaa")

 

備註:

1、代碼寫完以後,可以根據網頁上的在線aes密碼解析,對應我們的代碼輸出,檢查是不是可行的代碼

2、不論是加解密,都需要再進行一次base64的加解密,相結合

3、字符16位補齊的,去除的,在加解密中一定不要忘記

4、此文章只貼可行代碼,aes代碼加密原理自行百度

 

 

發佈了57 篇原創文章 · 獲贊 9 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章