AES算法

作者: flycloud_hz | 来源:发表于2017-10-20 15:36 被阅读0次

    0x0 AES介绍

    AES对数据对称加密,key大小为16,24,32个字节,每次加/解密输入16个字节,数据要做padding拼接,默认PKCS5Padding方式。

    OpenSSL可以选择aes.h或evp.h实现。

    0x1 代码实现

    h文件

    class AesCrypt {
    public:
        enum Mode {
            ENCRYPT = 0,
            DECRYPT
        };
    public:
        AesCrypt();
        ~AesCrypt();
        bool Init(Mode mode, const std::string& pass);
    
        bool Encrypt(const std::string& input, std::string& output);
        bool Decrypt(const std::string& input, std::string& output);
    
    private:
        Mode mode_;
        bool initialized_;
        AES_KEY ase_key_;
    };
    

    cpp文件

    AesCrypt::AesCrypt()
    : mode_(AesCrypt::DECRYPT), initialized_(false){
    
    }
    
    AesCrypt::~AesCrypt() {
    
    }
    
    bool AesCrypt::Encrypt(const std::string &input, std::string &output) {
        if (!initialized_) {
            LOGE("init not done");
            return  false;
        }
    
        if (mode_ == AesCrypt::DECRYPT) {
            LOGE("mode mismatch");
            return  false;
        }
    
        unsigned char buf[AES_BLOCK_SIZE];
        int inputLen = input.length();
        const unsigned char* inputPtr = (const unsigned char*)input.c_str();
        int i = 0;
        for (i = 0; i < inputLen / AES_BLOCK_SIZE; i ++) {
            AES_encrypt(inputPtr + i * AES_BLOCK_SIZE, buf, &ase_key_);
            output += std::string((const char*)buf, AES_BLOCK_SIZE);
        }
    
        // PKCS5Padding
        // 1. left > 0 : add paddding with (16 - left)
        // 2. left == 0 : add padding with 16
        int left = inputLen - i * AES_BLOCK_SIZE;
        if (left > 0) {
            unsigned char leftBuf[AES_BLOCK_SIZE];
            memset(leftBuf, AES_BLOCK_SIZE - left, AES_BLOCK_SIZE);
            memcpy(leftBuf, inputPtr + i * AES_BLOCK_SIZE, left);
            AES_encrypt(leftBuf, buf, &ase_key_);
            output += std::string((const char*)buf, AES_BLOCK_SIZE);
        } else {
            unsigned char leftBuf[AES_BLOCK_SIZE];
            memset(leftBuf, 16, AES_BLOCK_SIZE);
            AES_encrypt(leftBuf, buf, &ase_key_);
            output += std::string((const char*)buf, AES_BLOCK_SIZE);
        }
        return true;
    }
    
    bool AesCrypt::Decrypt(const std::string &input, std::string &output) {
        if (!initialized_) {
            LOGE("init not done");
            return  false;
        }
        if (mode_ == AesCrypt::ENCRYPT) {
            LOGE("mode mismatch");
            return  false;
        }
    
        unsigned char buf[AES_BLOCK_SIZE];
        int inputLen = input.length();
        const unsigned char* inputPtr = (const unsigned char*)input.c_str();
    
        for (int i = 0; i < inputLen / AES_BLOCK_SIZE; i ++) {
            AES_decrypt(inputPtr + i * AES_BLOCK_SIZE, buf, &ase_key_);
            output += std::string((const char*)buf, AES_BLOCK_SIZE);
        }
    
        // PKCS5Padding
        if (!output.empty() && output.length() >= 16) {
            int last = output.at(output.length() - 1);
            if (last <= 16) {
                output.erase(output.length() - last, last);
            } else {
                LOGE("decrypt data error");
            }
        }
        return true;
    }
    
    bool AesCrypt::Init(AesCrypt::Mode mode, const std::string &pass) {
        if (initialized_) {
            LOGE("init already done");
            return true;
        }
        int result;
        mode_ = mode;
        if (mode_ == AesCrypt::DECRYPT) {
            result = AES_set_decrypt_key((const unsigned char*)pass.c_str(), pass.length() * 8, &ase_key_);
        } else {
            result = AES_set_encrypt_key((const unsigned char*)pass.c_str(), pass.length() * 8, &ase_key_);
        }
        if (result < 0) {
            LOGE("AesCrypt constructor error");
        } else {
            initialized_ = true;
        }
        return initialized_;
    }
    

    相关文章

      网友评论

        本文标题:AES算法

        本文链接:https://www.haomeiwen.com/subject/sljvuxtx.html