zoukankan      html  css  js  c++  java
  • #微码分享#AES算法的C++包装类

    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 = ''; // 需要加上这一句,不然难区分HAVE_OPENSSL值是否为1或不为1的情况
    #endif // MOOON_HAVE_OPENSSL
    }
  • 相关阅读:
    微信小程序使用canvas画布实现当前页面截屏并分享
    微信小程序分享转发用法大全——自定义分享、全局分享、组合分享
    小程序条形码插件wxbarcode的使用及改进
    支付宝小程序开发——修改小程序原生radio默认样式
    常用maven配置
    Android Studio 星云常用配置工具箱
    星云最佳实践功法秘籍
    Intellij Idea 星云常用配置工具箱
    那些好用的Chrome 插件
    星云的Linux专用学习手册
  • 原文地址:https://www.cnblogs.com/aquester/p/10314381.html
Copyright © 2011-2022 走看看