c實現AES 128位加解密

//對應java的SecureRandom隨機密鑰
bool sha1prng_key(string str,char *out)
{
unsigned char result[20];

SHA1((unsigned char*)str.c_str(), strlen(str.c_str()), (unsigned char*)&result);
SHA1((unsigned char*)&result, 20, (unsigned char*)&result);

for (int i = 0; i < 20; i++) {
	//cout << hex << i;
	printf("%02x ", result[i]&0xFF);
}
cout << endl;	
memcpy(out,result,16);
return true;

}

//AES/ECB/PKCS5Padding
int padding(char *szIn,int len,char *szOut)
{
//補齊長度爲16的倍數
int iC = 16-len%16;

memcpy(szOut,szIn,len);
memset(&szOut[len],iC,iC);

return len+iC;

}

//AES/ECB/PKCS5Padding
int unpadding(char *szIn,int len,char *szOut)
{
//去掉補位字節
int iC = (int)szIn[len-1];

memcpy(szOut,szIn,len);
memset(&szOut[len-iC],0x0,iC);

return len-iC;

}

/**********************************************************
函數名:aes_encrypt
參數:const char* str_in --輸入字符
參數:unsigned char* key --key
參數:unsigned char* out --輸出字符
返回值:int --0失敗 1成功
說明:加密
********************************************************/
int aes_encrypt(char
str_in,int inLen, char
key, char
out)
{
char szKey[128];memset(szKey,0x0,sizeof(szKey));
sha1prng_key(key,szKey);

Auto_Pointer_pri app(inLen+32);
int len = padding(str_in,inLen,app.v_ptr);
	
printf("padding ...\n");
for (int ucIndex = 0; ucIndex < len; ucIndex++) {
	printf("%02x ", app.v_ptr[ucIndex]&0xFF);
}
printf("\n");
if (!str_in || !key || !out) return 0;

/*
//加密的初始化向量
unsigned char iv[AES_BLOCK_SIZE];

//16位密碼
char tmpIV[] = "0123456789abcdef";
for (int i = 0; i < 16; ++i)
    iv[i] = tmpIV[i];
*/
AES_KEY aes;
if (AES_set_encrypt_key((unsigned char*)szKey, 128, &aes) < 0)
{
    return 0;
}

//分段加密
for (int i=0;i<len;i++){
	if(i%16==0){
		//AES_cbc_encrypt((unsigned char*)str_in, (unsigned char*)out, len, &aes, iv, AES_ENCRYPT);
		AES_ecb_encrypt((unsigned char*)app.v_ptr+i, (unsigned char*)out+i,&aes, AES_ENCRYPT);
	}
}

for (int ucIndex = 0; ucIndex < len; ucIndex++) {
	printf("%02x ", out[ucIndex]&0xFF);
}
printf("\n");
return len;

}

/**********************************************************
函數名:aes_decrypt
參數:const char* str_in --輸入
參數:unsigned char* key --key
參數:unsigned char* out --輸出
返回值:int       --0失敗 1成功
說明:                --解密
********************************************************/
int aes_decrypt(char
str_in,int inLen, char
key, char
out)
{
char szKey[128];memset(szKey,0x0,sizeof(szKey));
sha1prng_key(key,szKey);

if (!str_in || !key || !out) return 0;

/*
unsigned char iv[AES_BLOCK_SIZE];//加密的初始化向量
char tmpIV[] = "0123456789abcdef";
for (int i = 0; i < 16; ++i)
    iv[i] = tmpIV[i];
*/	
AES_KEY aes;
if (AES_set_decrypt_key((unsigned char*)szKey, 128, &aes) < 0)
{
    return 0;
}
for (int ucIndex = 0; ucIndex < 16; ucIndex++) {
	printf("%02x ", aes.rd_key[ucIndex]&0xFF);
}
printf("\n");
int len = inLen;

//分段解密
for(int i=0;i<len;i++){
	if(i%16==0){
		//AES_cbc_encrypt((unsigned char*)str_in, (unsigned char*)out, len, &aes, iv, AES_DECRYPT);
		AES_ecb_encrypt((unsigned char*)str_in+i, (unsigned char*)out+i, &aes,AES_DECRYPT);
	}
}
for (int ucIndex = 0; ucIndex < len; ucIndex++) {
	printf("%02x ", out[ucIndex]&0xFF);
}
printf("\n");
int ioLen=unpadding(out,inLen,out);
return ioLen;

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章