#微码分享#AES算法的C++包装类

本文深入解析AES(高级加密标准)的实现原理与应用,AES是一种用于替代DES的区块加密算法,广泛应用于美国联邦政府及各类信息安全领域。文章通过C++示例代码详细介绍了AES的加密与解密过程,包括密钥处理、加密数据块分组长度的要求以及如何使用std::string实现AES算法。

AES为Advanced Encryption Standard的缩写,中文名:高级加密标准,在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准,用来替代DES。基于std::string实现的C++包装类,使用得应用AES算法十分简单。完整源代码链接:
​https://github.com/eyjian/libmooon/blob/master/include/mooon/utils/aes_helper.h
https://github.com/eyjian/libmooon/blob/master/src/utils/aes_helper.cpp​

aes_helper.h头文件

// 高级加密标准(Advanced Encryption Standard),
// 在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准,用来替代DES
class CAESHelper
{
public:
    // 加密数据块分组长度,必须为128比特(密钥长度可以是128比特、192比特、256比特中的任意一个)
    static int aes_block_size;

public:
    // key 密钥
    //
    // 因为AES要求key长度只能为128或192或256比特中的一种,即16字节或24字节或32字节中的一种,
    // 当key的长度不足16字节时,CAESHelper自动补0足16字节,
    // 当key的长度间于16字节和24字节时,CAESHelper自动补0足24字节,
    // 当key的长度间于24字节和32字节时,CAESHelper自动补0足32字节,
    // 当key的长度超出32字节时,CAESHelper自动截取前32字节作为密钥
    CAESHelper(const std::string& key);
    ~CAESHelper();

    void encrypt(const std::string& in, std::string* out);
    void decrypt(const std::string& in, std::string* out);

private:
    // flag 为true表示加密,为false表示解密
    void aes(bool flag, const std::string& in, std::string* out, void* aes_key);

private:
    void* _encrypt_key;
    void* _decrypt_key;
    std::string _key;
};

aes_helper.cpp实现文件

#if MOOON_HAVE_OPENSSL == 1
int CAESHelper::aes_block_size = AES_BLOCK_SIZE; // 16
#else
int CAESHelper::aes_block_size = 0;
#endif // MOOON_HAVE_OPENSSL

static std::string errcode2errmsg(int errcode)
{
    std::string errmsg;

    if (0 == errcode)
        errmsg = "success";
    else if (-1 == errcode)
        errmsg = "userkey is empty";
    else if (-2 == errcode)
        errmsg = "length of userkey is invalid";
    else
        errmsg = "unknown error";
    return errmsg;
}

CAESHelper::CAESHelper(const std::string& key)
{
    _encrypt_key = NULL;
    _decrypt_key = NULL;
    _key = key;

    const std::string::size_type LEN16 = 16;
    const std::string::size_type LEN24 = 24;
    const std::string::size_type LEN32 = 32;
    const std::string::size_type len = key.size();
    if ((len != LEN16) &&
        (len != LEN24) &&
        (len != LEN32))
    {
        if (len < LEN16)
            _key.resize(LEN16);
        else if (len < LEN24)
            _key.resize(LEN24);
        else if (len < LEN32)
            _key.resize(LEN32);
        else
            _key.resize(LEN32);
    }
}

CAESHelper::~CAESHelper()
{
#if MOOON_HAVE_OPENSSL == 1
    delete (AES_KEY*)_encrypt_key;
    delete (AES_KEY*)_decrypt_key;
#endif // MOOON_HAVE_OPENSSL
}

void CAESHelper::encrypt(const std::string& in, std::string* out)
{
#if MOOON_HAVE_OPENSSL == 1
    if (NULL == _encrypt_key)
    {
        _encrypt_key = new AES_KEY;

        const int errcode = AES_set_encrypt_key((const unsigned char*)(_key.data()), (int)(_key.size()*8), (AES_KEY*)_encrypt_key);
        if (errcode != 0) // 理论上不会返回非0,因为构造函数已经处理好了key的长度
        {
            delete (AES_KEY*)_encrypt_key;
            _encrypt_key = NULL;
            THROW_EXCEPTION(errcode2errmsg(errcode), errcode);
        }
    }

    aes(true, in, out, _encrypt_key);
#endif // MOOON_HAVE_OPENSSL
}

void CAESHelper::decrypt(const std::string& in, std::string* out)
{
#if MOOON_HAVE_OPENSSL == 1
    if (NULL == _decrypt_key)
    {
        _decrypt_key = new AES_KEY;

        const int errcode = AES_set_decrypt_key((const unsigned char*)(_key.data()), (int)(_key.size()*8), (AES_KEY*)_decrypt_key);
        if (errcode != 0) // 理论上不会返回非0,因为构造函数已经处理好了key的长度
        {
            delete (AES_KEY*)_decrypt_key;
            _decrypt_key = NULL;
            THROW_EXCEPTION(errcode2errmsg(errcode), errcode);
        }
    }

    aes(false, in, out, _decrypt_key);
#endif // MOOON_HAVE_OPENSSL
}

void CAESHelper::aes(bool flag, const std::string& in, std::string* out, void* aes_key)
{
#if MOOON_HAVE_OPENSSL == 1
    AES_KEY* aes_key_ = (AES_KEY*)aes_key;

    std::string in_tmp = in;
    if (in.size() % AES_BLOCK_SIZE != 0)
    {
        std::string::size_type tmp_size = in.size() + (AES_BLOCK_SIZE - in.size() % AES_BLOCK_SIZE);
        in_tmp.resize(tmp_size);
    }

    const char* in_p = in_tmp.data();
    out->resize(in_tmp.size());
    char* out_p = const_cast<char*>(out->data());

    for (std::string::size_type i=0; i<in.size(); i+=AES_BLOCK_SIZE)
    {
        char out_tmp[AES_BLOCK_SIZE];

        if (flag)
            AES_encrypt((const unsigned char*)(in_p), (unsigned char*)(out_tmp), aes_key_);
        else
            AES_decrypt((const unsigned char*)(in_p), (unsigned char*)(out_tmp), aes_key_);

        in_p += AES_BLOCK_SIZE;
        memcpy(out_p+i, out_tmp, AES_BLOCK_SIZE);
    }
#else
    *out = '\0'; // 需要加上这一句,不然难区分HAVE_OPENSSL值是否为1或不为1的情况
#endif // MOOON_HAVE_OPENSSL
}

 

06-22
### 微码技术实现与生成工具 微码是一种高效的信息编码方式,通常用于在有限的空间内存储更多的信息。相较于传统的一维码和二维码,微码具有更高的密度和更强的容错能力。以下是关于微码技术实现及生成工具的相关内容: #### 1. 微码的技术实现 微码的生成依赖于先进的编码算法和图像处理技术。以下是一些关键技术点[^3]: - **高密度编码**:微码通过优化编码规则,能够在更小的空间内存储更多信息。 - **错误校正机制**:微码通常采用 Reed-Solomon 等高级纠错算法,确保在部分损坏的情况下仍能正确解码。 - **多层数据结构**:微码可能包含多个数据层,每个层都可以独立编码和解码。 #### 2. 微码生成工具 目前市面上存在多种微码生成工具,包括开源库和商业软件。以下是几个常用的工具和库[^4]: - **ZXing Library**:这是一个开源的跨平台库,支持多种条形码和二维码格式,包括某些型的微码。可以通过自定义配置来生成微码。 - **OnBarcode**:这是一款商业工具,提供了丰富的 API 和图形界面,支持多种微码格式的生成和解析。 - **Micro QR Code Generator**:专注于生成 Micro QR Code(一种微码变种),适用于对空间要求极高的场景。 #### 3. C# 中生成微码的示例代码 以下是一个基于 ZXing 库的微码生成示例代码[^5]: ```csharp using System; using ZXing; using ZXing.QrCode; class Program { static void Main() { var qrWriter = new BarcodeWriter(); qrWriter.Format = BarcodeFormat.QR_CODE; // 可替换为其他微码格式 var options = new QrCodeEncodingOptions { Width = 200, Height = 200, Margin = 1 }; qrWriter.Options = options; string data = "This is a micrcode example"; var bitmap = qrWriter.Write(data); // 保存生成的微码图片 bitmap.Save("micrcode.png", System.Drawing.Imaging.ImageFormat.Png); } } ``` #### 4. 性能优化建议 在生成大量微码时,可以参考以下性能优化策略[^6]: - 使用更快的编码算法,例如选择更适合特定应用场景的微码格式。 - 减少数据量,通过压缩或摘要算法降低编码所需的时间。 - 利用多线程或异步处理,批量生成微码以提高效率。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值