使用mbedtls加解密(RSA AES)

时间:2021-05-10 18:31:52

 

tg_rsa.h

 

使用mbedtls加解密(RSA AES)使用mbedtls加解密(RSA AES)
// 注意: 编译mbedtls时, 添加宏 MBEDTLS_RSA_NO_CRT (基于 mbedtls 2.16.1)
#ifndef _BVR_OPENSSL_H_
#define _BVR_OPENSSL_H_

#include <iostream>
#include <string>

typedef struct mbedtls_rsa_context RSA;

bool tg_rsa_init();
bool tg_rsa_deinit();

// 生成密钥 bits >= 512
bool tg_rsa_key_generate(RSA** rsa, int bits);
// 密钥转为字符串
bool tg_rsa_key_string(RSA* rsa, std::string& n, std::string& e, std::string& d);
// 字符串转换为密钥
bool tg_rsa_key_get(RSA** rsa, const std::string& n, const std::string& e, const std::string& d = "");
// 释放rsa
bool tg_rsa_key_free(RSA* rsa);

// 密钥加密 usePubKey: 是否使用公钥加密
bool tg_rsa_encrypt(bool usePubKey, RSA* encrypt, std::string src, std::string& dst);

// 密钥解密 usePriKey: 是否使用私钥加密
bool tg_rsa_decrypt(bool usePriKey, RSA* decrypt, std::string src, std::string& dst);

/** base64 编码 */
std::string tg_base64_encode(const std::string& str_data);
/** base64 解码 */
std::string tg_base64_decode(const std::string& str_encoded);

/** aes cbc 加密 */
int tg_aes_cbc_encrypt(const std::string& plaintext, const std::string& key, const std::string& iv, std::string& ciphertext);
/** aes cbc 解密 */
int tg_aes_cbc_decrypt(const std::string& ciphertext, const std::string& key, const std::string& iv, std::string& plaintext);

/** 计算数据MD5值*/
std::string tg_md5_encode(const std::string& data);

#endif //_BVR_OPENSSL_H_
View Code

 

 

tg_rsa.cpp

 

使用mbedtls加解密(RSA AES)使用mbedtls加解密(RSA AES)
#include "tg_rsa.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "mbedtls/config.h"

#include "mbedtls/platform.h"

#include "mbedtls/rsa.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/error.h"
#include "mbedtls/base64.h"
#include "mbedtls/md5.h"

#ifdef _MSC_VER
#include <Windows.h>

#pragma comment(lib, "mbedcrypto.lib")
#pragma comment(lib, "mbedtls.lib")
#pragma comment(lib, "mbedx509.lib")
#endif

#define EXPONENT 65537
mbedtls_entropy_context m_entropy;
mbedtls_ctr_drbg_context m_ctr_drbg;

bool tg_rsa_init()
{
    const char *pers = "rsa_encrypt";
    int ret = -1;

    mbedtls_ctr_drbg_init(&m_ctr_drbg);
    mbedtls_entropy_init(&m_entropy);

    ret = mbedtls_ctr_drbg_seed(&m_ctr_drbg, mbedtls_entropy_func, &m_entropy, (const unsigned char *)pers, strlen(pers));
    return true;
}

bool tg_rsa_deinit()
{
    mbedtls_ctr_drbg_free(&m_ctr_drbg);
    mbedtls_entropy_free(&m_entropy);

    return true;
}

bool tg_rsa_key_generate(RSA** pp_rsa, int bits)
{
    mbedtls_rsa_context* p_rsa = NULL;
    int ret = -1;

    if (NULL == pp_rsa) {
        return false;
    }

    p_rsa = (mbedtls_rsa_context*)malloc(sizeof(mbedtls_rsa_context));
    mbedtls_rsa_init(p_rsa, MBEDTLS_RSA_PKCS_V15, 0);

    ret = mbedtls_rsa_gen_key(p_rsa, mbedtls_ctr_drbg_random, &m_ctr_drbg, bits, EXPONENT);
    if (0 == ret) {
        *pp_rsa = p_rsa;
    }

    return true;
}

bool tg_rsa_key_string(RSA* p_rsa, std::string& p_n, std::string& p_e, std::string& p_d)
{
    int ret = -1;
    int radix = 16;
    mbedtls_mpi N, D, E, P, Q;
    size_t olen_N = 0, olen_D = 0, olen_E = 0, olen_P = 0, olen_Q = 0;

    mbedtls_mpi_init(&N);
    mbedtls_mpi_init(&E);
    mbedtls_mpi_init(&D);
    mbedtls_mpi_init(&P);
    mbedtls_mpi_init(&Q);

    mbedtls_rsa_context* rsa = (mbedtls_rsa_context*)p_rsa;
    ret = mbedtls_rsa_export(rsa, &N, &P, &Q, &D, &E);

    int n = mbedtls_mpi_bitlen(&N);
    if (radix >= 4) n >>= 1;
    if (radix >= 16) n >>= 1;

    n += 3 + ((n + 1) & 1);
    p_n.resize(n);
    p_e.resize(n);
    p_d.resize(n);

    ret = mbedtls_mpi_write_string(&N, radix, (char*)p_n.data(), p_n.size(), &olen_N);
    ret = mbedtls_mpi_write_string(&E, radix, (char*)p_e.data(), p_e.size(), &olen_E);
    ret = mbedtls_mpi_write_string(&D, radix, (char*)p_d.data(), p_d.size(), &olen_D);

    p_n.resize(olen_N);
    p_e.resize(olen_E);
    p_d.resize(olen_D);

    mbedtls_mpi_free(&N);
    mbedtls_mpi_free(&E);
    mbedtls_mpi_free(&D);
    mbedtls_mpi_free(&P);
    mbedtls_mpi_free(&Q);

    return true;
}


bool tg_rsa_key_get(RSA** pp_rsa, const std::string& p_n, const std::string& p_e, const std::string& p_d /*= ""*/)
{
    bool rc = false;
    int radix = 16;
    int ret = -1;
    mbedtls_mpi N, D, E, P, Q;
    mbedtls_rsa_context* p_rsa = NULL;

    if (NULL == pp_rsa) {
        return false;
    }

    p_rsa = (mbedtls_rsa_context*)::malloc(sizeof(mbedtls_rsa_context));

    mbedtls_mpi_init(&N);
    mbedtls_mpi_init(&E);
    mbedtls_mpi_init(&D);
    mbedtls_mpi_init(&P);
    mbedtls_mpi_init(&Q);

    ret = mbedtls_mpi_read_string(&N, radix, p_n.data());
    ret = mbedtls_mpi_read_string(&E, radix, p_e.data());
    ret = mbedtls_mpi_read_string(&D, radix, p_d.data());
    ret = mbedtls_mpi_read_string(&P, radix, "1");
    ret = mbedtls_mpi_read_string(&Q, radix, "1");

    mbedtls_rsa_init(p_rsa, MBEDTLS_RSA_PKCS_V15, 0);

    ret = mbedtls_rsa_import(p_rsa, &N, &P, &Q, &D, &E);
    if (0 == ret) {
        *pp_rsa = p_rsa;
        rc = true;
    }

    mbedtls_mpi_free(&N);
    mbedtls_mpi_free(&E);
    mbedtls_mpi_free(&D);
    mbedtls_mpi_free(&P);
    mbedtls_mpi_free(&Q);

    return rc;
}

bool tg_rsa_key_free(RSA* p_rsa)
{
    mbedtls_rsa_context* rsa = (mbedtls_rsa_context*)p_rsa;
    if (rsa) {
        mbedtls_rsa_free(rsa);
        ::free(rsa);
    }

    return true;
}


/**
padding:
1)RSA_PKCS1_PADDING 填充模式,最常用的模式
要求:
输入 必须 比 RSA 钥模长(modulus) 短至少11个字节, 也就是 RSA_size(rsa) – 11。如果输入的明文过长,必须切割, 然后填充
输出 和modulus一样长

根据这个要求,对于1024bit的密钥, block length = 1024/8 – 11 = 117 字节

2) RSA_PKCS1_OAEP_PADDING
要求:RSA_size(rsa) – 41

3)for RSA_NO_PADDING 不填充
RSA_size(rsa)
*/


bool tg_rsa_encrypt(bool usePubKey, RSA* p_encrypt, std::string src, std::string& dst)
{
    mbedtls_rsa_context* encrypt = (mbedtls_rsa_context*)p_encrypt;
    /** 说明: rsa加密, 是将加密数据看做一个数字(大数), 进行加密。
    源数据的长度要小于密钥位数(FLEN_MAX), 加密后的长度是RSA_LEN。
    解密是将若干个RSA_LEN的块解密
    */
    int RSA_LEN = mbedtls_rsa_get_len(encrypt); // 512 = 4096 / 8
    int FLEN_MAX = RSA_LEN - 11;
    if (FLEN_MAX <= 0) { return false; }

    int count = src.size() / FLEN_MAX;
    int remain = src.size() % FLEN_MAX;

    size_t reserveSize = count * RSA_LEN + (remain > 0 ? RSA_LEN : 0); // 预留空间
    dst.reserve(reserveSize);

    std::string cipper;
    cipper.resize(RSA_LEN);

    unsigned char* from = (unsigned char*)src.data();
    unsigned char* to = (unsigned char*)cipper.data();

    int mode = MBEDTLS_RSA_PRIVATE;
    if (usePubKey) {
        mode = MBEDTLS_RSA_PUBLIC;
    }
    for (int i = 0; i < count; i++)
    {
        int ret = mbedtls_rsa_pkcs1_encrypt(encrypt, mbedtls_ctr_drbg_random, &m_ctr_drbg, mode,
            FLEN_MAX, (const unsigned char*)from + i * FLEN_MAX, to);

        if (ret != 0) {
            char pTmp[1024];
            mbedtls_strerror(ret, pTmp, 1024);
#ifdef _MSC_VER
            OutputDebugStringA(pTmp);
#endif
            printf("%s\n", pTmp);
            return false;
        }

        if (0 == ret){
            dst.append(cipper.data(), cipper.size());
        }
    }

    if (remain > 0)
    {
        int ret = mbedtls_rsa_pkcs1_encrypt(encrypt, mbedtls_ctr_drbg_random, &m_ctr_drbg, mode,
            remain, (const unsigned char*)from + count * FLEN_MAX, to);

        if (ret != 0) {
            char pTmp[1024];
            mbedtls_strerror(ret, pTmp, 1024);
#ifdef _MSC_VER
            OutputDebugStringA(pTmp);
#endif
            printf("%s\n", pTmp);
            return false;
        }

        dst.append(cipper.data(), cipper.size());
    }

    return true;
}

bool tg_rsa_decrypt(bool usePriKey, RSA* p_decrypt, std::string src, std::string& dst)
{
    mbedtls_rsa_context* decrypt = (mbedtls_rsa_context*)p_decrypt;
    int RSA_LEN = mbedtls_rsa_get_len(decrypt); // 512 = 4096 / 8

    int count = src.size() / RSA_LEN;
    int remain = src.size() % RSA_LEN;

    if (remain != 0) {
        return false;
    }

    size_t reserveSize = count * RSA_LEN; // 预留空间
    dst.reserve(reserveSize);

    std::string cipper;
    cipper.resize(RSA_LEN);

    unsigned char* from = (unsigned char*)src.data();
    unsigned char* to = (unsigned char*)cipper.data();

    int mode = MBEDTLS_RSA_PUBLIC;
    if (usePriKey) {
        mode = MBEDTLS_RSA_PRIVATE;
    }

    size_t elen = 0;
    for (int i = 0; i < count; i++)
    {
        // 解密
        int ret = mbedtls_rsa_pkcs1_decrypt(decrypt, mbedtls_ctr_drbg_random,
            &m_ctr_drbg, mode, &elen,
            from + i * RSA_LEN, to, cipper.size()); // output_max_len >= modulus_len - 11

        if (ret != 0)
        {
            char pTmp[1024];
            mbedtls_strerror(ret, pTmp, 1024);
#ifdef _MSC_VER
            OutputDebugStringA(pTmp);
#endif
            printf("%s\n", pTmp);
            return false;
        }

        dst.append(cipper.data(), elen);
    }

    return true;
}



std::string tg_base64_encode(const std::string& str_data)
{
    std::string result;
    size_t slen = str_data.size();
    size_t n = slen / 3 + (slen % 3 != 0);

    size_t dlen = 4 * n + 1;

    result.resize(dlen);

    unsigned char buffer[1024];
    memset(buffer, 0, sizeof(buffer));
    size_t olen = 0;
    int ret = mbedtls_base64_encode((unsigned char*)result.data(), result.size(),
        &olen,
        (const unsigned char*)str_data.data(), str_data.size());

    if (ret != 0)
    {
        char pTmp[1024];
        mbedtls_strerror(ret, pTmp, 1024);
#ifdef _MSC_VER
        OutputDebugStringA(pTmp);
#endif
        printf("%s\n", pTmp);
    }
    result.resize(olen);

    return result;
}

std::string tg_base64_decode(const std::string& str_encoded)
{
    std::string result;

    result.resize(str_encoded.size());

    size_t olen = 0;
    int ret = mbedtls_base64_decode((unsigned char*)result.data(), result.size(), &olen, (const unsigned char*)str_encoded.data(), str_encoded.size());
    if (ret != 0)
    {
        char pTmp[1024];
        mbedtls_strerror(ret, pTmp, 1024);
#ifdef _MSC_VER
        OutputDebugStringA(pTmp);
#endif
        printf("%s\n", pTmp);
    }

    result.resize(olen);

    return result;
}


int tg_aes_cbc_encrypt(const std::string& plaintext, const std::string& key, const std::string& iv, std::string& ciphertext)
{
    int rc = -1;
    size_t src_len = plaintext.size();
    size_t newsize = (src_len / 16) * 16;
    if (src_len % 16) {
        newsize += 16;
    }

    if (ciphertext.size() < newsize) {
        ciphertext.resize(newsize);
    }

    std::string src_data(plaintext);
    if (src_data.size() != newsize) {
        src_data.resize(newsize);

        // 兼容openssl, 填充位填充的数据为填充的长度
        int fill_len = newsize - src_len;
        for (size_t i = src_len; i < newsize; i++) {
            ((char*)src_data.data())[i] = (char)fill_len; // (0, 16)
        }
    }

    std::string tmp_iv(iv);
    const unsigned char* input = (const unsigned char*)src_data.data();
    unsigned char* output = (unsigned char*)ciphertext.data();

    mbedtls_aes_context ctx;
    mbedtls_aes_init(&ctx);

    rc = mbedtls_aes_setkey_enc(&ctx, (const unsigned char*)key.data(), key.size() * 8);

    rc = mbedtls_aes_crypt_cbc(&ctx,
        MBEDTLS_AES_ENCRYPT,
        newsize,
        (unsigned char*)tmp_iv.data(),
        input,
        output);

    mbedtls_aes_free(&ctx);

    return 0;
}

int tg_aes_cbc_decrypt(const std::string& ciphertext, const std::string& key, const std::string& iv, std::string& plaintext)
{
    int rc = -1;
    if (plaintext.size() < ciphertext.size()) {
        plaintext.resize(ciphertext.size());
    }

    size_t newsize = ciphertext.size();

    std::string tmp_iv(iv);
    const unsigned char* input = (const unsigned char*)ciphertext.data();
    unsigned char* output = (unsigned char*)plaintext.data();

    mbedtls_aes_context ctx;
    mbedtls_aes_init(&ctx);

    rc = mbedtls_aes_setkey_dec(&ctx, (const unsigned char*)key.data(), key.size() * 8);

    rc = mbedtls_aes_crypt_cbc(&ctx,
        MBEDTLS_AES_DECRYPT,
        newsize,
        (unsigned char*)tmp_iv.data(),
        input,
        output);

    // 兼容openssl, 填充位填充的数据为填充的长度
    {
        int fill_len = output[plaintext.size() - 1];
        if (fill_len > 0 && fill_len < 16)
        {
            bool is_ok = true;
            for (size_t i = plaintext.size() - fill_len; i < plaintext.size(); i++)
            {
                if (output[i] != fill_len) {
                    is_ok = false;
                    break;
                }
            }

            if (is_ok) {
                plaintext.resize(plaintext.size() - fill_len);
            }
            else {
                rc = -2;
            }
        }
    }

    mbedtls_aes_free(&ctx);

    return rc;
}

std::string tg_md5_encode(const std::string& src)
{
    std::string result;

    unsigned char output[17];
    memset(output, 0, sizeof(output));

    int rc = mbedtls_md5_ret((const unsigned char *)src.data(), src.size(), output);
    if (0 == rc)
    {
        char buffer[33];
        memset(buffer, 0, sizeof(buffer));
        for (int i = 0; i < 16; i++) {
            sprintf(buffer + i * 2, "%02x", output[i]);
        }

        result.assign(buffer, 32);
    }

    return result;
}


void test_tg_rsa()
{
    int rc = -1;
    tg_rsa_init();

    RSA* p_rsa = NULL;
    int bits = 2048;
    tg_rsa_key_generate(&p_rsa, bits);

    std::string n, e, d;
    tg_rsa_key_string(p_rsa, n, e, d);
    tg_rsa_key_free(p_rsa);

    RSA* tmp_rsa = NULL;
    tg_rsa_key_get(&tmp_rsa, n, e, d);

    std::string src = "视258频提供了功能强大的方法帮助您证明您的观点。当您单击联机视频时,可以在想要添加的视频的嵌入代码中进行粘贴。您也可以键入一个关键字以联机搜索最适合您的文档的视频。为使您的文档具有专业外观,Word 提供了页眉、页脚、封面和文本框设计,这些设计可互为补充。例如,您可以添加匹配的封面、页眉和提要栏。单击“插入”,然后从不同库中选择所需元素。主题和样式也有助于文档保持协调。当您单击设计并选择新的主题时,图片、图表或 SmartArt 图形将会更改以匹配新的主题。当应用样式时,您的标题会进行更改以匹配新的主题。使用在需要位置出现的新按钮在 Word 中保存时间。若要更改图片适应文档的方式,请单击该图片,图片旁边将会显示布局选项按钮。当处理表格时,单击要添加行或列的位置,然后单击加号。在新的阅读视图中阅读更加容易。可以折叠文档某些部分并关注所需文本。如果在达到结尾处之前需要停止读取,Word 会记住您的停止位置 - 即使在另一个设备上。123视258频提供了功能强大的方法帮助您证明您的观点。当您单击联机视频时,可以在想要添加的视频的嵌入代码中进行粘贴。您也可以键入一个关键字以联机搜索最适合您的文档的视频。为使您的文档具有专业外观,Word 提供了页眉、页脚、封面和文本框设计,这些设计可互为补充。例如,您可以添加匹配的封面、页眉和提要栏。单击“插入”,然后从不同库中选择所需元素。主题和样式也有助于文档保持协调。当您单击设计并选择新的主题时,图片、图表或 SmartArt 图形将会更改以匹配新的主题。当应用样式时,您的标题会进行更改以匹配新的主题。使用在需要位置出现的新按钮在 Word 中保存时间。若要更改图片适应文档的方式,请单击该图片,图片旁边将会显示布局选项按钮。当处理表格时,单击要添加行或列的位置,然后单击加号。在新的阅读视图中阅读更加容易。可以折叠文档某些部分并关注所需文本。如果在达到结尾处之前需要停止读取,Word 会记住您的停止位置 - 即使在另一个设备上。1234视258频提供了功能强大的方法帮助您证明您的观点。当您单击联机视频时,可以在想要添加的视频的嵌入代码中进行粘贴。您也可以键入一个关键字以联机搜索最适合您的文档的视频。为使您的文档具有专业外观,Word 提供了页眉、页脚、封面和文本框设计,这些设计可互为补充。例如,您可以添加匹配的封面、页眉和提要栏。单击“插入”,然后从不同库中选择所需元素。主题和样式也有助于文档保持协调。当您单击设计并选择新的主题时,图片、图表或 SmartArt 图形将会更改以匹配新的主题。当应用样式时,您的标题会进行更改以匹配新的主题。使用在需要位置出现的新按钮在 Word 中保存时间。若要更改图片适应文档的方式,请单击该图片,图片旁边将会显示布局选项按钮。当处理表格时,单击要添加行或列的位置,然后单击加号。在新的阅读视图中阅读更加容易。可以折叠文档某些部分并关注所需文本。如果在达到结尾处之前需要停止读取,Word 会记住您的停止位置 - 即使在另一个设备上。123视258频提供了功能强大的方法帮助您证明您的观点。当您单击联机视频时,可以在想要添加的视频的嵌入代码中进行粘贴。您也可以键入一个关键字以联机搜索最适合您的文档的视频。为使您的文档具有专业外观,Word 提供了页眉、页脚、封面和文本框设计,这些设计可互为补充。例如,您可以添加匹配的封面、页眉和提要栏。单击“插入”,然后从不同库中选择所需元素。主题和样式也有助于文档保持协调。当您单击设计并选择新的主题时,图片、图表或 SmartArt 图形将会更改以匹配新的主题。当应用样式时,您的标题会进行更改以匹配新的主题。使用在需要位置出现的新按钮在 Word 中保存时间。若要更改图片适应文档的方式,请单击该图片,图片旁边将会显示布局选项按钮。当处理表格时,单击要添加行或列的位置,然后单击加号。在新的阅读视图中阅读更加容易。可以折叠文档某些部分并关注所需文本。如果在达到结尾处之前需要停止读取,Word 会记住您的停止位置 - 即使在另一个设备上。12345";
    std::string dst, dst2;
    tg_rsa_encrypt(true, tmp_rsa, src, dst);
    tg_rsa_decrypt(true, tmp_rsa, dst, dst2);


    std::string base64 = tg_base64_encode("this is test");
    std::string debase64 = tg_base64_decode(base64);

    {
        int32_t key_rand = 128;
        int32_t iv_rand = 5;

        std::string key;/* A 256 bit key */  // 256/8=32 "01234567890123456789012345678901"
        std::string iv;/* A 128 bit IV */ // 128/8=16 "0123456789012345"
        {
            const int KEY_SIZE_256_BIT = 32;
            key.resize(KEY_SIZE_256_BIT);
            for (int i = 0; i < KEY_SIZE_256_BIT; i++) {
                key[i] = (2 * i * i * i + 7 * i + key_rand) % 256;
            }

            const int IV_SIZE_128_BIT = 16;
            iv.resize(IV_SIZE_128_BIT);
            for (int i = 0; i < IV_SIZE_128_BIT; i++) {
                iv[i] = (6 * i * i * i + 8 * i + iv_rand) % 256;
            }
        }

        unsigned char output[100];
        unsigned char output2[100];
        mbedtls_aes_context ctx_encrypt, ctx_decrypt;

        memset(output, 0x00, 100);
        memset(output2, 0x00, 100);

        unsigned char src_str[1024];
        memset(src_str, 0, sizeof(src_str));
        strcpy((char*)src_str, "this is");
        size_t len = strlen((char*)src_str);
        if (len % 16) {
            len = len / 16 * 16 + 16;
        }

        mbedtls_aes_init(&ctx_encrypt);
        mbedtls_aes_init(&ctx_decrypt);

        rc = mbedtls_aes_setkey_enc(&ctx_encrypt, (const unsigned char*)key.data(), key.size() * 8);
        rc = mbedtls_aes_setkey_dec(&ctx_decrypt, (const unsigned char*)key.data(), key.size() * 8);

        rc = mbedtls_aes_crypt_cbc(&ctx_encrypt, MBEDTLS_AES_ENCRYPT,
            len, (unsigned char*)iv.data(),
            (const unsigned char*)src_str, output);

        {
            const int IV_SIZE_128_BIT = 16;
            iv.resize(IV_SIZE_128_BIT);
            for (int i = 0; i < IV_SIZE_128_BIT; i++) {
                iv[i] = (6 * i * i * i + 8 * i + iv_rand) % 256;
            }
        }
        rc = mbedtls_aes_crypt_cbc(&ctx_decrypt, MBEDTLS_AES_DECRYPT,
            16, (unsigned char*)iv.data(),
            (const unsigned char*)output, output2);

        mbedtls_aes_free(&ctx_encrypt);
        mbedtls_aes_free(&ctx_decrypt);
    }
    {
        int32_t key_rand = 128;
        int32_t iv_rand = 5;

        std::string key;/* A 256 bit key */  // 256/8=32 "01234567890123456789012345678901"
        std::string iv;/* A 128 bit IV */ // 128/8=16 "0123456789012345"
        {
            const int KEY_SIZE_256_BIT = 32;
            key.resize(KEY_SIZE_256_BIT);
            for (int i = 0; i < KEY_SIZE_256_BIT; i++) {
                key[i] = (2 * i * i + 5 * i + key_rand) % 256;
            }

            const int IV_SIZE_128_BIT = 16;
            iv.resize(IV_SIZE_128_BIT);
            for (int i = 0; i < IV_SIZE_128_BIT; i++) {
                iv[i] = (6 * i * i + 20 * i + iv_rand) % 256;
            }
        }

        std::string plaintext = "1234567890123456789012345678901234567";
        std::string ciphertext, src;
        tg_aes_cbc_encrypt(plaintext, key, iv, ciphertext);
        const char* ptr = ciphertext.data();

        std::string base64 = tg_base64_encode(ciphertext);
        std::string debase64 = tg_base64_decode("0D7z6lI1x8SRMtLBk6jBiGAEZdazu/9ZkZhNGjaZC7DeABaboX33F885Otlh/mt8");

        tg_aes_cbc_decrypt(debase64, key, iv, src);
        const char* ptr2 = src.data();
        printf("");
    }

    {
        std::string data = "this is hello";
        std::string md5 = tg_md5_encode(data);
        printf("");

        std::string str1 = set_cert_txt_openssl("this is hello 中文");
        std::string str2 = get_cert_txt_openssl(str1);

        printf("");
    }

    tg_rsa_key_free(tmp_rsa);

    tg_rsa_deinit();
}
View Code