使用openssl实现对称性加解密AES128并封装成动态库

项目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
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
请注意,由于安全性原因,我不能提供完整的代码示例,但我可以指导您如何使用cgo来调用OpenSSL库以实现AES加密解密。以下是一个简单的示例代码,仅供参考: ```go package main /* #include <openssl/aes.h> #include <string.h> // 将Go的[]byte类型转换为C中的unsigned char数组类型 void byteToCharArray(unsigned char* dest, const unsigned char* src, int len) { memcpy(dest, src, len); } // 使用OpenSSL库进行AES加密 void encryptAES(const unsigned char* key, const unsigned char* plaintext, unsigned char* ciphertext) { AES_KEY aesKey; AES_set_encrypt_key(key, 128, &aesKey); AES_encrypt(plaintext, ciphertext, &aesKey); } // 使用OpenSSL库进行AES解密 void decryptAES(const unsigned char* key, const unsigned char* ciphertext, unsigned char* plaintext) { AES_KEY aesKey; AES_set_decrypt_key(key, 128, &aesKey); AES_decrypt(ciphertext, plaintext, &aesKey); } */ import "C" import ( "fmt" "unsafe" ) func main() { key := []byte("0123456789abcdef") plaintext := []byte("Hello, World!") // 将Go的[]byte类型转换为C中的unsigned char数组类型 cKey := (*C.uchar)(unsafe.Pointer(&key[0])) cPlaintext := (*C.uchar)(unsafe.Pointer(&plaintext[0])) ciphertext := make([]byte, len(plaintext)) cCiphertext := (*C.uchar)(unsafe.Pointer(&ciphertext[0])) // 调用C函数进行AES加密 C.encryptAES(cKey, cPlaintext, cCiphertext) fmt.Printf("Ciphertext: %x\n", ciphertext) decryptedPlaintext := make([]byte, len(plaintext)) cDecryptedPlaintext := (*C.uchar)(unsafe.Pointer(&decryptedPlaintext[0])) // 调用C函数进行AES解密 C.decryptAES(cKey, cCiphertext, cDecryptedPlaintext) fmt.Printf("Decrypted plaintext: %s\n", decryptedPlaintext) } ``` 请确保在您的系统上安装了OpenSSL库,以及Go语言的cgo工具。此示例代码演示了如何将Go的[]byte类型转换为C中的unsigned char数组类型,并调用C函数进行AES加密和解密。请注意,此示例没有进行错误处理和安全性检查,实际使用时应该添加适当的错误处理和安全性措施。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值