//
// Created by MyPC on 2021/4/17.
//
#include "aesencode.h"
#include <stdlib.h>
#include <openssl/aes.h>
#include <openssl/base64.h>
#include <time.h>
#include "string.h"
#include "android/log.h"
#include "mybase64.h"
#define LOG_TAG "WD_COLLECT"
#define LOGV(...)  __android_log_print(ANDROID_LOG_VERBOSE,LOG_TAG,__VA_ARGS__);

void generateAESKeyIv(char *key, char*iv, char* key_Table);
void encrpyt_buf(char*m_key,char*m_iv, char *raw_buf, char **encrpy_buf, int len );
void decrpyt_buf(char*m_key,char*m_iv, char *raw_buf, char **encrpy_buf, int len );
int startAESEncode(char*m_key,char*m_iv, char* src,int src_Size,char**encode_ptr,int* out_size);

char *padding_buf(char *buf,int size, int *final_size);




char *padding_buf(char *buf,int size, int *final_size) {
    char *ret = NULL;
    //填充区的大小
    int pidding_size = AES_BLOCK_SIZE - (size % AES_BLOCK_SIZE);
    int i;
    *final_size = size + pidding_size;
    ret = (char *)calloc(1,size+pidding_size);
    memcpy( ret, buf, size);
    if (pidding_size!=0) {
        for (i =size;i < (size+pidding_size); i++ ) {
            ret[i] = 0;
        }
    }
    return ret;
}

int startAESEncode(char*m_key,char*m_iv, char* src,int src_Size,char**encode_ptr,int* out_size){
    if(src== NULL||src_Size<=0){
        return 0;
    }
    char *after_padding_buf = NULL;
    int padding_size = 0;
    char *encrypt_buf = NULL;
    //进行填充
    after_padding_buf = padding_buf(src,src_Size,&padding_size);
    if(after_padding_buf==NULL){
        return 0;
    }
    // 进行加密
    encrypt_buf = (char *)calloc(1,padding_size);
    encrpyt_buf(m_key,m_iv,after_padding_buf,&encrypt_buf, padding_size);
    free(after_padding_buf);
    //传出加密后的内容
    *encode_ptr = encrypt_buf;
    *out_size=padding_size;
    //-----------------测试代码
    //打印源字符串的16进制
    unsigned char* temp=( unsigned char*)calloc(1,padding_size*2+1);
    int strLen=padding_size;
    for(int i=0;i<strLen;++i){
        char temp2[0x10]={0};
        sprintf(temp2,"%02x",encrypt_buf[i]);
        strcat((char *)(temp), (char *)(temp2));
    }
    LOGV("测试代码->AES加密后的二进制字符串：%s",temp);
    free(temp);
    // 重新解密
    char *decrypt_buf = NULL;
    decrypt_buf = (char *)calloc(1,padding_size);
    decrpyt_buf(m_key,m_iv, encrypt_buf,&decrypt_buf,padding_size);
    LOGV("测试代码->AES重新解密后：%s",decrypt_buf);
    free(decrypt_buf);
    //----------------------------





    return 1;
}

void generateAESKeyIv(char *key,char*iv,char* key_Table){
    for(int i=0;i<16;i++){
        key[i]=key_Table[rand()%16];
    }
    for(int i=0;i<16;i++){
        iv[i]=key_Table[rand()%16];
    }
}
void encrpyt_buf(char*m_key,char*m_iv, char *raw_buf, char **encrpy_buf, int len ) {
    AES_KEY aes;
    unsigned char key[17] = {0};
    unsigned char iv[] = {0};
    memcpy(key,m_key,0x10);
    memcpy(iv,m_iv,0x10);
//    LOGV("m_key= %s",key);
//    LOGV("m_iv= %s",m_iv);
    AES_set_encrypt_key((const uint8_t *)(m_key), 128, &aes);
    AES_cbc_encrypt((const uint8_t *)(raw_buf),
                    ( uint8_t *)(*encrpy_buf),
                    len, &aes, ( uint8_t *)(iv), AES_ENCRYPT);
//    free(key);
}
void decrpyt_buf(char*m_key,char*m_iv, char *raw_buf, char **encrpy_buf, int len ) {
    AES_KEY aes;
    unsigned char key[17] = {0};
//    unsigned char iv[] =  "1234567890123457";
    unsigned char iv[]={0};
    memcpy(key,m_key,0x10);
    memcpy(iv,m_iv,0x10);
//    LOGV("m_key= %s",key);
//    LOGV("m_iv= %s",m_iv);
    AES_set_decrypt_key(( uint8_t *)(m_key), 128, &aes);
    AES_cbc_encrypt(( uint8_t *)(raw_buf),
                    ( uint8_t *)(*encrpy_buf), len, &aes,
                    ( uint8_t *)(iv), AES_DECRYPT);
}




void aes_Encoder_Base64(char *src,int src_Len,char**encode_ptr,char*out_key,char*out_iv ){
    //用于密钥生成的表
    char key_Table[]="0123456789abcdef";
    //用于接收AES加密后的内容
    char *aes_Encode_Content= 0;
    //用于接收AES加密后的内容的长度
    int aes_Encode_Count=0;
    srand(time(0));
    //开始随机生成KEY和IV
    generateAESKeyIv(out_key,out_iv,key_Table);
    //开始进行AES加密
    startAESEncode(out_key,out_iv,src,src_Len,&aes_Encode_Content,&aes_Encode_Count);
    if(aes_Encode_Content!= 0&&aes_Encode_Count>0){
        //------------BASE64 加密
        //计算加密后的长度
        int num=(aes_Encode_Count/3)*4;
        num=num+aes_Encode_Count % 3 ;
        //开始加密
        char *encode= (char*)(calloc(1,num+1));
        Base64Encode(aes_Encode_Content,aes_Encode_Count,encode);
        free(aes_Encode_Content);

        LOGV("测试代码->对AES获取的密文进行Base64加密: %s ",encode);
        //传出结果
        *encode_ptr=encode;

        //测试代码：BASE64 解密
        char *decode= (char*)(calloc(1,num));
        Base64Decode(encode,strlen(encode),decode);

        unsigned char* temp=(unsigned char*)calloc(1,aes_Encode_Count*2+1);
        int strLen=aes_Encode_Count;
        for(int i=0;i<strLen;++i){
            char temp2[0x10]={0};
            sprintf(temp2,"%02x",decode[i]);
            strcat((char*)(temp), (char *)(temp2));
        }
        LOGV("测试代码->重新解密Base64->AES加密后的二进制字符串：%s",temp);
        free(temp);
        free(decode);
        //


    }else{
        LOGV("AES加密失败");
    }
}