#define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1))
#define ALIGN_DATA_BYTE 16 // 16 * 8 128 bit
#define ALIGN_KEY 128
#define ERROR_SUCCESS 0
#define ERROR_NULL 1
#define ERROR_LEN_ZERO 2
#define ERROR_MALLOC_FAIL 3
#define ERROR_KEY_FAIL 4
// because the source data
int EncodeAES(const char const *source, unsigned int sourceLen, char* const dest, const char const* key)
{
if (NULL == source || NULL == dest || NULL == key)
{
return ERROR_NULL;
}
if (0 == sourceLen)
{
return ERROR_LEN_ZERO;
}
int compeleteSourceLen = ALIGN(sourceLen, ALIGN_DATA_BYTE);
int i = 0;
int count = compeleteSourceLen / AES_BLOCK_SIZE;
char* destTemp = dest;
AES_KEY aes_key;
if (AES_set_encrypt_key((const unsigned char*)key, ALIGN_KEY, &aes_key) < 0)
{
return ERROR_KEY_FAIL;
}
// the data size of input can't be align to 16 bytes, but the size of output data must be align to 16 bytes
for (i = 0; i < count; i++)
{
char* str16 = source + i * AES_BLOCK_SIZE;
unsigned char out[AES_BLOCK_SIZE];
memset(out, 0, AES_BLOCK_SIZE);
AES_encrypt((const unsigned char*)str16, out, &aes_key);
memcpy(destTemp, (const char*)out, AES_BLOCK_SIZE);
destTemp += AES_BLOCK_SIZE;
}
return ERROR_SUCCESS;
}
int DecodeAES(const char* const source, char* const dest, int destLen, const char* const key)
{
if (NULL == source || NULL == dest || NULL == key)
{
return ERROR_NULL;
}
if (0 == destLen)
{
return ERROR_LEN_ZERO;
}
char* str16;
char* destTemp = dest;
int i = 0;
int count = destLen / AES_BLOCK_SIZE;
AES_KEY aes_key;
if (AES_set_decrypt_key((const unsigned char*)key, ALIGN_KEY, &aes_key) < 0)
{
return ERROR_KEY_FAIL;
}
for (i = 0; i < count; i++)
{
str16 = source + i * AES_BLOCK_SIZE;
unsigned char out[AES_BLOCK_SIZE];
memset(out, 0, AES_BLOCK_SIZE);
AES_decrypt((const unsigned char*)str16, out, &aes_key);
memcpy(destTemp, (const char*)out, AES_BLOCK_SIZE);
destTemp += AES_BLOCK_SIZE;
}
if (destLen % AES_BLOCK_SIZE != 0)
{
str16 = source + i * AES_BLOCK_SIZE;
unsigned char out[destLen % AES_BLOCK_SIZE];
memset(out, 0, destLen % AES_BLOCK_SIZE);
AES_decrypt((const unsigned char*)str16, out, &aes_key);
memcpy(destTemp, (const char*)out, destLen % AES_BLOCK_SIZE);
}
return 0;
}
int main()
{
char* strSource = "xubuju hello world";
char* strDest = (char*) malloc(32);
char* strKey = "hello wo";
int result = EncodeAES(strSource, 18, strDest, strKey);
//free(strDest);
printf("strDest = %s", strDest);
strSource = (char*) malloc(18);
DecodeAES(strDest, strSource, 18, strKey);
printf("strSource = %s", strSource);
return 0;
}
AES 加密
int EncodeAES(const char const *source, unsigned int sourceLen, char* const dest, const char const* key)
函数作用:将字符加密
参数说明:
source: 加密前的数据
sourceLen:加密前的数据 长度,函数里面会做对齐处理,所以在输入的时候这个长度是多少就是多少
dest: 加密后的数据 对齐16字节之后的数加密数据
key: 加密用的密钥
返回值: 0 成功, 1 source 为空 , 2 长度为0, 3 设置加密密钥失败
注意:
1. 密钥的输入source 的长度可以不定,最后生成的对应的数据必然是16字节对齐的数,所以在使用这个接口前
malloc dest的时候,长度一定要用对齐后的长度:#define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1)) 如ALIGN(18, 16) = 32
2. key 的长度也可以不定,所以长度就可以不用输入
3. 当然这些值不可以是NULL或者长度为0
AES 解密
int DecodeAES(const char* const source, char* const dest, int destLen, const char* const key)
函数作用:将字符解密
参数说明:
source: 加密前的数据 解密的数据必然是16字节对齐的,所以不用输入
dest: 加密后的数据
destLen: 加密后的数据长度 这里的长度是:没有对齐前的长度 ALIGN(18, 16) = 32 , 这里的长度就是18 ,malloc的时候要注意
key: 加密用的密钥
返回值: 0 成功, 1 source 为空 , 2 长度为0, 3 设置加密密钥失败
因为上面的接口都不是字符,所以不能用strXXXX:strlen, 要用memXXX, memcpy