AES加密解密(CBC模式,pkcs5padding填充方式)
PKCS5Padding:填充的原则是,如果长度少于16个字节,需要补满16个字节,补(16-len)个(16-len)例如:
huguPozhen这个节符串是9个字节,16-9= 7,补满后如:huguozhen+7个十进制的7
如果字符串长度正好是16字节,则需要再补16个字节的十进制的16。
加密实现后的调用:
QString key = "qwertyuiopasdfghjklzxcvbnm789456"; //密钥
QString ivec = "123456789zxcvbnm"; //偏移量
QString code = "helloworld"; //待加密内容
QString EnResult = AesCode::enCode( key, ivec, code ); //加密后内容
函数原型:
static QString enCode( QString key, QString ivec, QString code );
static int aes_encrypt(unsigned char* in,unsigned char* key,unsigned char* ivec,unsigned char* out);
具体实现:
// AES_BLOCK_SIZE 16
int AesCode::aes_encrypt(unsigned char *in, unsigned char *key ,unsigned char* ivec, unsigned char *out)
{
if(!in || !key || !out) return 0;
AES_KEY aes;
if(AES_set_encrypt_key(key, 256, &aes) < 0)
{
return 0;
}
/**
* pkcs5padding
**/
int dateSize = strlen( (char*)in ) + 1;
int nLen = strlen( (char*)in );
int nBei = nLen / AES_BLOCK_SIZE + 1;
int nTotal = nBei * AES_BLOCK_SIZE;
char *enc_s = (char*)malloc(nTotal);
int nNumber;
if (nLen % 16 > 0)
nNumber = nTotal - nLen;
else
nNumber = 16;
memset(enc_s, nNumber, nTotal);
memcpy(enc_s, in, nLen);
AES_cbc_encrypt((unsigned char*)enc_s, out, nTotal, &aes, ivec, AES_ENCRYPT);
return 1;
}
//MSG_LEN 10240
QString AesCode::enCode(QString key, QString ivec, QString code)
{
unsigned char sourceStringTemp[MSG_LEN];
memset((unsigned char*)sourceStringTemp, 0x00 ,MSG_LEN);
strcpy( (char*)sourceStringTemp, code.toLatin1().constData() );
unsigned char keyArray[AES_BLOCK_SIZE*2];
memset((unsigned char*)keyArray, 0x00 ,AES_BLOCK_SIZE*2);
strcpy( (char*)keyArray, key.toLatin1().constData() );
unsigned char codeKey[AES_BLOCK_SIZE*2];
for (int j = 0; j < AES_BLOCK_SIZE*2 ; ++j) {
codeKey[j] = keyArray[j];
}
unsigned char codeIvec[ivec.size()];
for(int j = 0; j < ivec.size(); ++j) {
codeIvec[j] = ivec[j].unicode();
}
unsigned char result[MSG_LEN];
memset((unsigned char*)result, 0x00 ,MSG_LEN);
if( !aes_encrypt(sourceStringTemp,codeKey,codeIvec,result) ) {
qDebug() << "Encode Error";
return "";
}
QByteArray by_result = (char*)result;
QString s_result(by_result.toBase64());
memset((char*)sourceStringTemp, 0x00 ,MSG_LEN);
return s_result;
}
解密实现后的调用:
AesCode::deCode( key, ivec, EnResult );
函数原型:
static QString deCode( QString key, QString ivec, QString code );
static int aes_decrypt(unsigned char* in,unsigned char* key,unsigned char* ivec,unsigned char* out);
具体实现:
int AesCode::aes_decrypt(unsigned char *in, unsigned char *key, unsigned char* ivec, unsigned char *out)
{
if(!in || !key || !out) return 0;
AES_KEY aes;
if(AES_set_decrypt_key(key, 256, &aes) < 0)
{
return 0;
}
int dateSize = strlen( (char*)in );
AES_cbc_encrypt(in, out, dateSize, &aes, ivec, AES_DECRYPT);
/**
* pack5padding,获取最后一位数,以该数为个数,将out指向区域的最后位数用0替代
**/
int out_len = strlen((char*)out);
int last_value = (unsigned char)out[out_len-1];
memset(out+out_len-last_value, 0, last_value);
return 1;
}
QString AesCode::deCode(QString ivec, QString code, QString key)
{
unsigned char sourceStringTemp[MSG_LEN];
memset((unsigned char*)sourceStringTemp, 0x00 ,MSG_LEN);
strcpy( (char*)sourceStringTemp, code.toLatin1().constData() );
unsigned char keyArray[AES_BLOCK_SIZE*2];
memset((unsigned char*)keyArray, 0x00 ,AES_BLOCK_SIZE*2);
strcpy( (char*)keyArray, key.toLatin1().constData() );
unsigned char codeKey[AES_BLOCK_SIZE*2];
for (int j = 0; j < AES_BLOCK_SIZE*2 ; ++j) {
codeKey[j] = keyArray[j];
}
unsigned char codeIvec[ivec.size()];
for(int j = 0; j < ivec.size(); ++j) {
codeIvec[j] = ivec[j].unicode();
}
QByteArray by_result = (char*)sourceStringTemp;
QByteArray base64Result = QByteArray::fromBase64(by_result);
unsigned char result[MSG_LEN];
memset((unsigned char*)result, 0x00 ,MSG_LEN);
if( !aes_decrypt((unsigned char *)base64Result.constData(),codeKey,codeIvec,result) ) {
qDebug() << "Decode Error";
return "";
}
QString s_result = (char*)result;
memset((char*)sourceStringTemp, 0x00 ,MSG_LEN);
return s_result;
}