RSA算法(C++)

RSA加解密过程

RSA为非对称加密算法,由一对公钥和一对私钥构成,私钥加密公钥解密,公钥加密私钥解密
如下图,D为私密的,假设传输英文字母,我们给英文字母编号A=1,B=2,C=3…
在这里插入图片描述

RSA加解密过程

两对密钥产生方法如下
在这里插入图片描述

C++ OpenSSL库实现加解密

#include <openssl/rsa.h> // 包含OpenSSL RSA加密算法相关函数
#include <openssl/pem.h> // 包含PEM格式编码和解码函数
#include <openssl/err.h> // 包含错误处理函数
#include <iostream>      // 包含标准输入输出流
#include <cstring>       // 包含C字符串处理函数
#include <vector>        // 包含向量容器
#include <memory>        // 包含智能指针
#include <stdexcept>     // 包含标准异常类

// RSAEncryptor类用于封装RSA加密和解密操作
class RSAEncryptor
{
private:
    // 使用智能指针管理RSA结构体和BIGNUM结构体资源
    std::unique_ptr<RSA, decltype(&RSA_free)> rsa;
    std::unique_ptr<BIGNUM, decltype(&BN_free)> bn;

public:
    // 构造函数,初始化RSA密钥对
    RSAEncryptor() : rsa(RSA_new(), RSA_free), bn(BN_new(), BN_free)
    {
        // 设置公钥指数为RSA_F4(65537),这是一个常用的公钥指数
        BN_set_word(bn.get(), RSA_F4);
        // 生成2048位的RSA密钥对
        if (RSA_generate_key_ex(rsa.get(), 2048, bn.get(), nullptr) != 1)
        {
            // 如果密钥生成失败,抛出异常
            throw std::runtime_error("RSA key generation failed");
        }
    }

    // 析构函数,默认即可,智能指针会自动释放资源

    // 加密函数,接收一个字符串,返回加密后的字节数组
    std::vector<unsigned char> encrypt(const std::string &plaintext)
    {
        // 获取RSA密钥长度
        int rsa_size = RSA_size(rsa.get());
        // 创建足够大的缓冲区来存储加密数据
        std::vector<unsigned char> encrypted(rsa_size);
        
        // 执行公钥加密操作
        int result = RSA_public_encrypt(plaintext.size(),
                                        reinterpret_cast<const unsigned char *>(plaintext.data()),
                                        encrypted.data(),
                                        rsa.get(),
                                        RSA_PKCS1_PADDING);
        // 如果加密失败,抛出异常
        if (result == -1)
        {
            throw std::runtime_error("RSA encryption failed");
        }

        // 调整vector大小以匹配加密后的数据长度
        encrypted.resize(result);
        return encrypted;
    }

    // 解密函数,接收加密后的字节数组,返回解密后的字符串
    std::string decrypt(const std::vector<unsigned char> &ciphertext)
    {
        // 获取RSA密钥长度
        int rsa_size = RSA_size(rsa.get());
        // 创建足够大的缓冲区来存储解密数据
        std::vector<unsigned char> decrypted(rsa_size);

        // 执行私钥解密操作
        int result = RSA_private_decrypt(ciphertext.size(),
                                         ciphertext.data(),
                                         decrypted.data(),
                                         rsa.get(),
                                         RSA_PKCS1_PADDING);
        // 如果解密失败,抛出异常
        if (result == -1)
        {
            throw std::runtime_error("RSA decryption failed");
        }

        // 将解密后的数据转换为字符串
        return std::string(decrypted.begin(), decrypted.begin() + result);
    }
};

// 主函数,演示RSAEncryptor类的使用
int main()
{
    try
    {
        // 创建RSAEncryptor实例
        RSAEncryptor encryptor;

        // 原始消息
        std::string original_message = "你好, RSA!";
        // 加密消息
        std::vector<unsigned char> encrypted_message = encryptor.encrypt(original_message);
        // 解密消息
        std::string decrypted_message = encryptor.decrypt(encrypted_message);

        // 输出原始消息
        std::cout << "原信息: " << original_message << std::endl;
        // 输出加密后的数据
        std::cout << "加密数据: ";
        for (auto c : encrypted_message)
        {
            std::cout << std::hex << static_cast<int>(c);
        }
        std::cout << std::endl;
        // 输出解密后的数据
        std::cout << "解密数据: " << decrypted_message << std::endl;
    }
    catch (const std::exception &e)
    {
        // 如果发生异常,输出错误信息
        std::cerr << "发生错误: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}

编译运行:

g++ -o rsa_example RSA.cpp -lssl -lcrypto

运行结果:
在这里插入图片描述

为了保证数据传输的安全性,RSA算法是一种非常常见的加密算法。在C语言中,可以使用以下代码实现RSA算法: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/rsa.h> #include <openssl/pem.h> #include <openssl/err.h> #define KEY_LENGTH 2048 #define PUB_EXP 3 int main(int argc, char *argv[]) { char *pub_key_path = "public.pem"; // 公钥路径 char *pri_key_path = "private.pem"; // 私钥路径 char *plain_text = "Hello, RSA!"; // 明文 char cipher_text[256] = {0}; // 密文 char decrypt_text[256] = {0}; // 解密后的明文 // 1. 生成密钥对 RSA *rsa = RSA_generate_key(KEY_LENGTH, PUB_EXP, NULL, NULL); if (rsa == NULL) { printf("RSA_generate_key error.\n"); return -1; } // 2. 保存公钥和私钥 FILE *fp = NULL; fp = fopen(pub_key_path, "wb+"); if (fp == NULL) { printf("fopen public key error.\n"); return -1; } PEM_write_RSAPublicKey(fp, rsa); fclose(fp); fp = fopen(pri_key_path, "wb+"); if (fp == NULL) { printf("fopen private key error.\n"); return -1; } PEM_write_RSAPrivateKey(fp, rsa, NULL, NULL, 0, NULL, NULL); fclose(fp); // 3. 使用公钥加密 fp = fopen(pub_key_path, "rb"); if (fp == NULL) { printf("fopen public key error.\n"); return -1; } RSA *public_key = RSA_new(); if (public_key == NULL) { printf("RSA_new public_key error.\n"); return -1; } public_key = PEM_read_RSAPublicKey(fp, &public_key, NULL, NULL); fclose(fp); int rsa_len = RSA_public_encrypt(strlen(plain_text), (unsigned char *)plain_text, (unsigned char *)cipher_text, public_key, RSA_PKCS1_PADDING); if (rsa_len == -1) { printf("RSA_public_encrypt error.\n"); return -1; } printf("cipher text: %s\n", cipher_text); // 4. 使用私钥解密 fp = fopen(pri_key_path, "rb"); if (fp == NULL) { printf("fopen private key error.\n"); return -1; } RSA *private_key = RSA_new(); if (private_key == NULL) { printf("RSA_new private_key error.\n"); return -1; } private_key = PEM_read_RSAPrivateKey(fp, &private_key, NULL, NULL); fclose(fp); rsa_len = RSA_private_decrypt(rsa_len, (unsigned char *)cipher_text, (unsigned char *)decrypt_text, private_key, RSA_PKCS1_PADDING); if (rsa_len == -1) { printf("RSA_private_decrypt error.\n"); return -1; } printf("decrypt text: %s\n", decrypt_text); return 0; } ``` 注意,在使用该代码时需要安装openssl库。可以使用以下命令在Ubuntu上安装openssl: ```shell sudo apt-get install libssl-dev ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值