C++ OpenSSL 3.0.8 AES加解密

这篇具有很好参考价值的文章主要介绍了C++ OpenSSL 3.0.8 AES加解密。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  2023年后,openssl进入3.0版本,openssl的加解密代码也出现了一些变化,例如编译时会有如下错误:

error C4996: ‘AES_set_encrypt_key’: Since OpenSSL 3.0

  如果使用OpenSSL 1.1.1 sdk编译则没有上述错误,使用3.0以上的openssl sdk就会报错,那是因为3.0的不兼容1.0的sdk。如果你想继续使用已弃用的函数,并且不想更改代码,可以考虑禁用特定的编译警告。在 Visual Studio 中,你可以使用 #pragma warning(disable: 4996) 来禁用这个特定的警告。请注意,这并不是一个推荐的解决方案,因为它可能会掩盖潜在的问题。最佳的解决方案通常是更新你的代码,以使用新的API。这样可以确保你的代码与最新的库版本兼容,并且可以从新版本中获得的安全和性能改进中受益。

  下面是C++ OpenSSL 3.0 AES加解密的代码:

#pragma once

#include <iostream>
#include <vector>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <string>
#include <codecvt>
#include <sstream>
#include <iomanip>

class CEncrypt3 {
private:
    CEncrypt3() {
        const unsigned char fixed_key[32] = { 0x71, 0x02, 0x03, 0x04, 0x05, 0x06, 0x17, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x4A, 0x0F, 0x10,
                                              0x11, 0x12, 0x53, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0xFC, 0x10, 0x1E, 0x1F, 0x20 };
        const unsigned char fixed_iv[16] = { 0x21, 0x02, 0x03, 0xA4, 0x05, 0x06, 0x23, 0x08, 0x09, 0x0A, 0x1B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 };

        std::copy(fixed_key, fixed_key + sizeof(key), key);
        std::copy(fixed_iv, fixed_iv + sizeof(iv), iv);
    }

public:
    static CEncrypt3& Instance() {
        static CEncrypt3 instance;
        return instance;
    }

    CEncrypt3(const CEncrypt3&) = delete;
    CEncrypt3& operator=(const CEncrypt3&) = delete;

    std::wstring Encrypt(const std::wstring& plaintext)
    {
        if (plaintext.empty())
            return L"";

        std::vector<unsigned char> ciphertext;
        EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
        if (!ctx)
        {
            throw std::runtime_error("Failed to create cipher context");
        }

        if (EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv) != 1)
        {
            EVP_CIPHER_CTX_free(ctx);
            throw std::runtime_error("Failed to initialize encryption");
        }

        std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
        std::string utf8_text = converter.to_bytes(plaintext);

        int len;
        ciphertext.resize(utf8_text.size() + EVP_CIPHER_block_size(EVP_aes_256_cbc()));
        if (EVP_EncryptUpdate(ctx, ciphertext.data(), &len, reinterpret_cast<const unsigned char*>(utf8_text.data()), utf8_text.size()) != 1)
        {
            EVP_CIPHER_CTX_free(ctx);
            throw std::runtime_error("Failed to encrypt data");
        }

        int padding_len;
        if (EVP_EncryptFinal_ex(ctx, ciphertext.data() + len, &padding_len) != 1)
        {
            EVP_CIPHER_CTX_free(ctx);
            throw std::runtime_error("Failed to finalize encryption");
        }

        ciphertext.resize(len + padding_len);
        EVP_CIPHER_CTX_free(ctx);

        std::wstringstream wss;
        for (auto c : ciphertext) {
            wss << std::hex << std::setw(2) << std::setfill(L'0') << (int)c;
        }

        return wss.str();
    }

    std::wstring Decrypt(const std::wstring& ciphertext)
    {
        if (ciphertext.empty())
            return L"";

        std::vector<unsigned char> ciphertext_bytes;
        for (size_t i = 0; i < ciphertext.size(); i += 2) {
            std::wstring byte_string = ciphertext.substr(i, 2);
            unsigned char byte = static_cast<unsigned char>(std::stoi(byte_string, nullptr, 16));
            ciphertext_bytes.push_back(byte);
        }

        std::vector<unsigned char> plaintext;
        EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
        if (!ctx)
        {
            throw std::runtime_error("Failed to create cipher context");
        }

        if (EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv) != 1)
        {
            EVP_CIPHER_CTX_free(ctx);
            throw std::runtime_error("Failed to initialize decryption");
        }

        int len;
        plaintext.resize(ciphertext_bytes.size());
        if (EVP_DecryptUpdate(ctx, plaintext.data(), &len, ciphertext_bytes.data(), ciphertext_bytes.size()) != 1)
        {
            EVP_CIPHER_CTX_free(ctx);
            throw std::runtime_error("Failed to decrypt data");
        }

        int padding_len;
        if (EVP_DecryptFinal_ex(ctx, plaintext.data() + len, &padding_len) != 1)
        {
            EVP_CIPHER_CTX_free(ctx);
            throw std::runtime_error("Failed to finalize decryption");
        }

        plaintext.resize(len + padding_len);
        EVP_CIPHER_CTX_free(ctx);

        std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
        return converter.from_bytes(reinterpret_cast<const char*>(plaintext.data()), reinterpret_cast<const char*>(plaintext.data() + plaintext.size()));
    }

private:
    unsigned char key[32];
    unsigned char iv[16];
};



int main()
{
    CEncrypt3& instance = CEncrypt3::Instance();

    std::wstring plaintext = L"中文加密解密容易出现乱码";

    std::wstring ciphertext = instance.Encrypt(plaintext);
    std::wstring decrypted_text = instance.Decrypt(ciphertext);

    std::wcout << L"Original text: " << plaintext << std::endl;
    std::wcout << L"Decrypted text: " << decrypted_text << std::endl;

    return 0;
}

CEncrypt3用了单例模式,在其它地方调用时,使用CEncrypt3::Instance().Encrypt(plaintext)即可。文章来源地址https://www.toymoban.com/news/detail-663361.html

到了这里,关于C++ OpenSSL 3.0.8 AES加解密的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 20230721在WIN10下安装openssl并解密AES-128加密的ts视频切片

    20230721在WIN10下安装openssl并解密AES-128加密的ts视频切片 2023/7/21 22:58 1、前言: AES-128加密的ts视频切片【第一个】,打开有时间限制的! https://app1ce7glfm1187.h5.xiaoeknow.com/v2/course/alive/l_64af6130e4b03e4b54da1681?type=2app_id=app1cE7gLFM1187pro_id=term_645c69388953e_Nhew9Aavailable=trueshare_user_id=u_5e591188

    2024年02月16日
    浏览(31)
  • OpenSSL中AES加密的用法

    原文链接: https://blog.csdn.net/mao834099514/article/details/54945776 密码学中的高级加密标准(Advanced Encryption Standard,AES),又称 Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级

    2024年02月08日
    浏览(36)
  • php7使用openssl_encrypt函数进行AES加密

    前言 手上有个api对接需求,要用到AES加密,要用到openssl_encrypt函数,记录一下,鉴权要求大概如下。 将明文先base64加密,后取前16位 判断字符串的字节型数据长度是否为16倍整,如不是则进行补充(PKCS#7标准) 对字符串进行AES加密后base64加密,其中 iv=A-16-Byte-String 介绍 参数

    2023年04月08日
    浏览(29)
  • openssl3.2 - 官方demo学习 - mac - cmac-aes256.c

    指定加密算法(e.g. AES-256-CBC), 对明文生成MAC数据

    2024年01月19日
    浏览(49)
  • C++ CryptoPP使用AES加解密

    Crypto++ (CryptoPP) 是一个用于密码学和加密的 C++ 库。它是一个开源项目,提供了大量的密码学算法和功能,包括对称加密、非对称加密、哈希函数、消息认证码 (MAC)、数字签名等。Crypto++ 的目标是提供高性能和可靠的密码学工具,以满足软件开发中对安全性的需求。 高级加密

    2024年02月05日
    浏览(33)
  • 解决cryptoJS.AES默认参数加密,java无法解密的问题

    有时候我们需要跨编程语言进行加密加密。比如nodejs里面加密,java里面解密,或者反过来java加密,nodejs解密。node可以使用cryptojs,java可以使用javax.crypto.Cipher包。 网上有很多关于这方面的文章。然而如果node使用了默认的参数进行加密(比如现有业务已经生成了一些已经加密

    2024年02月11日
    浏览(90)
  • 前端使用AES密码加密、解密,使用详细(crypto加密解密,前后端分离,AES加密解密)

    1、 首先安装 crypto-js插件,安装命令如下:    -S等同于--save,保存在package.json文件中,是在dependencies 下, --save安装包信息将加入到dependencies(生产环境)中,生产阶段的依赖,也就是项目运行时的依赖,就是程序上线后仍然需要依赖; -D等同于--save-dev,也保存在package.j

    2024年02月11日
    浏览(48)
  • 前端CryptoJS-AES加解密 对应php的AES-128-CBC加解密踩坑(java也相同加解密)

     前端部分注意看填充是pkcs7 有个前提,要看前端有没有转成hex格式,如果没转,php那边就不需要调用特定函数转hex格式的 后端php代码

    2024年02月15日
    浏览(38)
  • 使用AES加解密异常

    问题 :有八台机器,一台机器出现解密失败,出现 java.security.InvalidKeyException: Illegal key size 解决 :最初没有错误信息,进行盲排预估是编码问题,最后排除了系统编码问题,后面增加日志出现上述异常,查找信息发现是jce包下的jar因为技术受限导致的错误,所以开始比较机器

    2024年02月08日
    浏览(28)
  • 前端AES加密解密

    前端经常会遇到这种接口和参数需要加密的情况,目前用的最多的就是aes加密了。以下就是操作步骤。以下方式适用各个前端框架,请自行根据框架修改对应语法 1.安装 CryptoJS 这个库就是用来加密的核心,直接打开项目终端,输入 npm install crypto-js --save 2. 新建 crypto.js 在 @/

    2024年02月13日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包