项目github地址:项目地址
头文件 aes128.h
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <openssl/aes.h>
#include <iostream>
namespace aes128 {
using UCHAR = unsigned char;
using UCHARPTR = unsigned char*;
class AES128 {
public:
AES128 ();
int InitIv(UCHARPTR iv); //随机初始化偏移量iv
int ZeroPaddingLength(UCHARPTR raw_str); //设置加解密字符串长度,非16字节倍数则用0补齐
inline int GetDataLen() {return set_data_len_;}
// UCHARPTR GetIv();
// void SetIv(UCHARPTR iv);
/*AES加密:
入参:明文、偏移量、加密秘钥
出参:密文
*/
int AES_Encrypt(UCHARPTR raw_str, UCHARPTR iv, UCHARPTR key, UCHARPTR encrypt_data);
/*AES解密:
入参:密文、偏移量、解密秘钥
出参:明文
*/
int AES_Decrypt(UCHARPTR raw_str, UCHARPTR iv, UCHARPTR key, UCHARPTR decrypt_data);
private:
// UCHARPTR iv_;
// UCHARPTR key_;
AES_KEY aes_key_;
int set_data_len_;
};
}
源文件 aes128.cc
#include "aes128.h"
using namespace std;
namespace aes128 {
AES128::AES128():set_data_len_(0) {
memset(&aes_key_, 0x00, sizeof(AES_KEY));
}
int AES128::InitIv(UCHARPTR iv) {
int up_case(0), ascii_code(0);
if (iv == nullptr) {
return -1;
}
srand((int)time(0));
for(int i = 0; i < AES_BLOCK_SIZE; i++) {
up_case = rand() % 3; //随机为2或1或0,为2就是数字,为1就是大写,为0就是小写
if (up_case == 2) {
ascii_code = rand()%('9'-'0'+1) + '0';
} else if (up_case == 1) {
ascii_code = rand()%('Z'-'A'+1) + 'A';
} else {
ascii_code = rand()%('z'-'a'+1) + 'a';
}
iv[i] = (unsigned char)ascii_code;
// iv[i] = 0;
}
return 0;
}
int AES128::ZeroPaddingLength(UCHARPTR raw_str) {
if (raw_str == nullptr) {
return -1;
}
int data_len = 0;
while (*(raw_str++)) {
++data_len;
}
if ((data_len%AES_BLOCK_SIZE) == 0) {
set_data_len_ = data_len;
} else {
set_data_len_ = ((data_len/AES_BLOCK_SIZE)+1) * AES_BLOCK_SIZE;
}
return 0;
}
int AES128::AES_Encrypt(UCHARPTR raw_str, UCHARPTR iv, UCHARPTR key, UCHARPTR encrypt_data) {
if (raw_str == nullptr || iv == nullptr || key == nullptr || encrypt_data == nullptr) {
return -1;
}
// printf("iv: ");
// for(int i = 0; i < AES_BLOCK_SIZE; i++) {
// printf("%02x", iv[i]);
// }
// printf("\n");
//设置加密密钥
memset(&aes_key_, 0x00, sizeof(AES_KEY));
if (AES_set_encrypt_key(key, 128, &aes_key_) < 0) {
std::cout << "Unable to set encryption key in AES..." << std::endl;
return -1;
}
// printf("raw_str: ");
// for(int i = 0; i < AES_BLOCK_SIZE; i++) {
// printf("%02x", raw_str[i]);
// }
// printf("\n");
// printf("key: ");
// for(int i = 0; i < AES_BLOCK_SIZE; i++) {
// printf("%02x", key[i]);
// }
//加密
AES_cbc_encrypt(raw_str, encrypt_data, set_data_len_, &aes_key_, iv, AES_ENCRYPT);
return 0;
}
int AES128::AES_Decrypt(UCHARPTR raw_str, UCHARPTR iv, UCHARPTR key, UCHARPTR decrypt_data) {
if (raw_str == nullptr || iv == nullptr || key == nullptr || decrypt_data == nullptr) {
return -1;
}
// printf("iv: ");
// for(int i = 0; i < AES_BLOCK_SIZE; i++) {
// printf("%02x", iv[i]);
// }
// printf("\n");
//设置解密密钥
memset(&aes_key_, 0x00, sizeof(AES_KEY));
if(AES_set_decrypt_key(key, 128, &aes_key_) < 0) {
std::cout << "Unable to set decryption key in AES..." << std::endl;
return -1;
}
// printf("raw_str: ");
// for(int i = 0; i < AES_BLOCK_SIZE; i++) {
// printf("%02x", raw_str[i]);
// }
// printf("\n");
// printf("key: ");
// for(int i = 0; i < AES_BLOCK_SIZE; i++) {
// printf("%02x", key[i]);
// }
//解密
AES_cbc_encrypt(raw_str, decrypt_data, set_data_len_, &aes_key_, iv, AES_DECRYPT);
return 0;
}
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(AES128)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11 -g")
set(CMAKE_CXX_FLAGS_DEBUG "-g -Wall")
set(CMAKE_BUILD_TYPE DEBUG)
# option(PLATFORM "compile platform" arm) #默认arm平台
add_definitions(-DNDEBUG) #屏蔽DEBUG信息
#include_directories
include_directories(
${PROJECT_SOURCE_DIR}/include
)
#link_directories
link_directories(
${PROJECT_SOURCE_DIR}/lib
)
set(SOURCES
${PROJECT_SOURCE_DIR}/src/aes128.cc
)
#.so
add_library(aes128 SHARED ${SOURCES})
# target libraries
target_link_libraries(
aes128
m
crypto
dl
)
测试文件 test.cc
#include "../include/aes128.h"
int main() {
int resCode(0);
aes128::AES128 aes;
aes128::UCHAR iv[AES_BLOCK_SIZE];
aes128::UCHAR iv_dec[AES_BLOCK_SIZE];
aes128::UCHAR key[AES_BLOCK_SIZE+1] = "AaBbCcDd1234!@#$";
aes128::UCHAR raw_str[3][AES_BLOCK_SIZE] = {"admin", "abc123456", "123456cba"};
aes128::UCHARPTR input_data = nullptr;
aes128::UCHARPTR encrypt_data = nullptr;
aes128::UCHARPTR decrypt_data = nullptr;
resCode = aes.InitIv(iv);
printf("iv init: ");
for(int i = 0; i < AES_BLOCK_SIZE; i++) {
printf("%02x", iv[i]);
}
printf("\n");
memcpy(iv_dec, iv, AES_BLOCK_SIZE);
for (int k = 0; k < 3; ++k) {
aes.ZeroPaddingLength(raw_str[k]);
input_data = (aes128::UCHARPTR)calloc(aes.GetDataLen()+1, sizeof(aes128::UCHARPTR));
memcpy(input_data, raw_str[k], strlen((char *)raw_str[k]));
//加密测试
encrypt_data = (aes128::UCHARPTR)calloc(aes.GetDataLen()+1, sizeof(aes128::UCHARPTR));
resCode = aes.AES_Encrypt(input_data, iv, key, encrypt_data);
printf("\nencrypt_data: ");
for(int i = 0; i < aes.GetDataLen(); i++) {
printf("%02x", encrypt_data[i]);
}
printf("\n");
//解密测试
decrypt_data = (aes128::UCHARPTR)calloc(strlen((char *)encrypt_data), sizeof(aes128::UCHARPTR));
resCode = aes.AES_Decrypt(encrypt_data, iv_dec, key, decrypt_data);
// printf("\ndecrypt_data: ");
// for(int i = 0; i < strlen((char *)encrypt_data); i++) {
// printf("%02x", decrypt_data[i]);
// }
printf("\ndecrypt_data: %s\n", (char *)decrypt_data);
if (input_data != nullptr) {
free(input_data);
input_data = nullptr;
}
if (encrypt_data != nullptr) {
free(encrypt_data);
encrypt_data = nullptr;
}
if (decrypt_data != nullptr) {
free(decrypt_data);
decrypt_data = nullptr;
}
}
return 0;
}
//g++ --std=c++11 test.cc -o test -L ../build/ -laes128
//export LD_LIBRARY_PATH=/home/zzg/AES128/build/:$LD_LIBRARY_PATH