C++使用openssl rsa进行加密、解密和签名验证

一、RSA是一种非对称加密算法,一般在数据加密的过程中会使用公钥加密,私钥解密,在签名生成和验证过程中会使用私钥加密,公钥解密。

二、使用openssl生成公钥和私钥

1、生成私钥,保存在文件rsa_private_key.pem里面
openssl genrsa -out rsa_private_key.pem 1024

2、通过私钥生成公钥,保存在文件rsa_private_key.pem里面
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

三、openssl公钥加密,私钥解密(私钥和公钥通过文件传进去),这里有一个注意点是在通过私钥解密的读取私钥信息时候使用的是PEM_read_bio_RSAPrivateKey,但是通过公钥加密读取公钥信息的时候使用的是PEM_read_bio_RSA_PUBKEY,而不是PEM_read_bio_RSAPublicKey。

// 通过公钥文件加密
std::vector<char> EncryptByPubkeyFile(const std::string& message,
                                      const std::string& pub_filename) {
    BIO* in = BIO_new(BIO_s_file());
    if (in == NULL) {
        std::cout << "BIO_new failed" << std::endl;
        return std::vector<char>();
    }
    BIO_read_filename(in, pub_filename.c_str());

    RSA* rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
    BIO_free(in);
    if (rsa == NULL) {
        std::cout << "PEM_read_bio_RSA_PUBKEY failed" << std::endl;
        return std::vector<char>();
    }
    int size = RSA_size(rsa);
    std::vector<char> encrypt_data;
    encrypt_data.resize(size);
    int ret = RSA_public_encrypt(
        message.length(), (unsigned char*)message.c_str(),
        (unsigned char*)encrypt_data.data(), rsa, RSA_PKCS1_PADDING);
    RSA_free(rsa);
    if (ret == -1) {
        std::cout << "RSA_public_encrypt failed" << std::endl;
        return std::vector<char>();
    }
    return encrypt_data;
}

// 通过私钥文件解密
std::string DecryptByPrikeyFile(char* cipher, uint32_t len,
                                const std::string& pri_file) {
    BIO* in = BIO_new(BIO_s_file());
    if (in == NULL) {
        std::cout << "BIO_new failed" << std::endl;
        return "";
    }
    BIO_read_filename(in, pri_file.c_str());

    RSA* rsa = PEM_read_bio_RSAPrivateKey(in, NULL, NULL, NULL);
    BIO_free(in);
    if (rsa == NULL) {
        std::cout << "PEM_read_bio_RSAPrivateKey failed" << std::endl;
        return "";
    }

    int size = RSA_size(rsa);
    std::vector<char> data;
    data.resize(size);
    int ret = RSA_private_decrypt(len, (unsigned char*)cipher,
                                  (unsigned char*)data.data(), rsa,
                                  RSA_PKCS1_PADDING);
    RSA_free(rsa);
    if (ret == -1) {
        std::cout << "RSA_private_decrypt failed" << std::endl;
        return "";
    }
    std::string decrypt_data(data.begin(), data.end());
    return decrypt_data;
}

四、openssl公钥加密,私钥解密(私钥和公钥通过字符串传进去)

// 通过公钥字符串进行加密
std::vector<char> EncryptByPubkeyString(const std::string& message,
                                        const std::string& pubkey) {
    BIO* in = BIO_new_mem_buf((void*)pubkey.c_str(), -1);
    if (in == NULL) {
        std::cout << "BIO_new_mem_buf failed" << std::endl;
        return std::vector<char>();
    }

    RSA* rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
    BIO_free(in);
    if (rsa == NULL) {
        std::cout << "PEM_read_bio_RSA_PUBKEY failed" << std::endl;
        return std::vector<char>();
    }

    int size = RSA_size(rsa);
    std::vector<char> encrypt_data;
    encrypt_data.resize(size);
    int ret = RSA_public_encrypt(
        message.length(), (unsigned char*)message.c_str(),
        (unsigned char*)encrypt_data.data(), rsa, RSA_PKCS1_PADDING);
    RSA_free(rsa);
    if (ret == -1) {
        std::cout << "RSA_public_encrypt failed" << std::endl;
        return std::vector<char>();
    }

    return encrypt_data;
}

// 通过私钥字符串进行解密
std::string DecryptByPrikeyString(char* cipher, uint32_t len,
                                  const std::string prikey) {
    BIO* in = BIO_new_mem_buf((void*)prikey.c_str(), -1);
    if (in == NULL) {
        std::cout << "BIO_new_mem_buf failed" << std::endl;
        return "";
    }

    RSA* rsa = PEM_read_bio_RSAPrivateKey(in, NULL, NULL, NULL);
    BIO_free(in);
    if (rsa == NULL) {
        std::cout << "PEM_read_bio_RSAPrivateKey failed" << std::endl;
        return "";
    }

    int size = RSA_size(rsa);
    std::vector<char> data;
    data.resize(size);
    int ret = RSA_private_decrypt(len, (unsigned char*)cipher,
                                  (unsigned char*)data.data(), rsa,
                                  RSA_PKCS1_PADDING);
    RSA_free(rsa);
    if (ret == -1) {
        std::cout << "RSA_private_decrypt failed" << std::endl;
        return "";
    }
    std::string decrypt_data(data.begin(), data.end());
    return decrypt_data;
}

五、openssl私钥加密,公钥解密(私钥和公钥通过文件传进去),一般用来生成和验证签名

// 通过私钥文件加密
std::vector<char> EncryptByPrikeyFile(const std::string& message,
                                      const std::string& pri_file) {
    BIO* in = BIO_new(BIO_s_file());
    if (in == NULL) {
        std::cout << "BIO_new failed" << std::endl;
        return std::vector<char>();
    }
    BIO_read_filename(in, pri_file.c_str());

    RSA* rsa = PEM_read_bio_RSAPrivateKey(in, NULL, NULL, NULL);
    BIO_free(in);
    if (rsa == NULL) {
        std::cout << "PEM_read_bio_RSAPrivateKey failed" << std::endl;
        return std::vector<char>();
    }
    int size = RSA_size(rsa);
    std::vector<char> encrypt_data;
    encrypt_data.resize(size);
    int ret = RSA_private_encrypt(
        message.length(), (unsigned char*)message.c_str(),
        (unsigned char*)encrypt_data.data(), rsa, RSA_PKCS1_PADDING);
    RSA_free(rsa);
    if (ret == -1) {
        std::cout << "RSA_private_encrypt failed" << std::endl;
        return std::vector<char>();
    }
    return encrypt_data;
}

// 通过公钥文件解密
std::string DecryptByPubkeyFile(char* cipher, uint32_t len,
                                const std::string& pub_filename) {
    BIO* in = BIO_new(BIO_s_file());
    if (in == NULL) {
        std::cout << "BIO_new failed" << std::endl;
        return "";
    }
    BIO_read_filename(in, pub_filename.c_str());

    RSA* rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
    BIO_free(in);
    if (rsa == NULL) {
        std::cout << "PEM_read_bio_RSA_PUBKEY failed" << std::endl;
        return "";
    }

    int size = RSA_size(rsa);
    std::vector<char> data;
    data.resize(size);
    int ret =
        RSA_public_decrypt(len, (unsigned char*)cipher,
                           (unsigned char*)data.data(), rsa, RSA_PKCS1_PADDING);
    RSA_free(rsa);
    if (ret == -1) {
        std::cout << "RSA_public_decrypt failed" << std::endl;
        return "";
    }
    std::string decrypt_data(data.begin(), data.end());
    return decrypt_data;
}

六、openssl私钥加密,公钥解密(私钥和公钥通过字符串传进去),一般用来生成和验证签名

// 通过私钥字符串加密
std::vector<char> EncryptByPrikeyString(const std::string& message,
                                        const std::string& prikey) {
    BIO* in = BIO_new_mem_buf((void*)prikey.c_str(), -1);
    if (in == NULL) {
        std::cout << "BIO_new_mem_buf failed" << std::endl;
        return std::vector<char>();
    }

    RSA* rsa = PEM_read_bio_RSAPrivateKey(in, NULL, NULL, NULL);
    BIO_free(in);
    if (rsa == NULL) {
        std::cout << "PEM_read_bio_RSAPrivateKey failed" << std::endl;
        return std::vector<char>();
    }

    int size = RSA_size(rsa);
    std::vector<char> encrypt_data;
    encrypt_data.resize(size);
    int ret = RSA_private_encrypt(
        message.length(), (unsigned char*)message.c_str(),
        (unsigned char*)encrypt_data.data(), rsa, RSA_PKCS1_PADDING);
    RSA_free(rsa);
    if (ret == -1) {
        std::cout << "RSA_private_encrypt failed" << std::endl;
        return std::vector<char>();
    }

    return encrypt_data;
}

// 通过公钥字符串解密
std::string DecryptByPubkeyString(char* cipher, uint32_t len,
                                  const std::string& pubkey) {
    BIO* in = BIO_new_mem_buf((void*)pubkey.c_str(), -1);
    if (in == NULL) {
        std::cout << "BIO_new_mem_buf failed" << std::endl;
        return "";
    }

    RSA* rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
    BIO_free(in);
    if (rsa == NULL) {
        std::cout << "PEM_read_bio_RSA_PUBKEY failed" << std::endl;
        return "";
    }

    int size = RSA_size(rsa);
    std::vector<char> data;
    data.resize(size);
    int ret =
        RSA_public_decrypt(len, (unsigned char*)cipher,
                           (unsigned char*)data.data(), rsa, RSA_PKCS1_PADDING);
    RSA_free(rsa);
    if (ret == -1) {
        std::cout << "RSA_public_decrypt failed" << std::endl;
        return "";
    }
    std::string decrypt_data(data.begin(), data.end());
    return decrypt_data;
}

七、openssl私钥生成签名,公钥验证签名(私钥和公钥通过文件传进去),这里传进去的message是一个文件的md5值,所以在RSA_sign函数和RSA_verify函数的第一个参数使用NID_md5

// 通过私钥文件生成签名
std::vector<char> GenerateRsaSignByFile(const std::string& message,
                                        const std::string& pri_filename) {
    OpenSSL_add_all_algorithms();
    BIO* in = BIO_new(BIO_s_file());
    if (in == NULL) {
        std::cout << "BIO_new failed" << std::endl;
        return std::vector<char>();
    }
    BIO_read_filename(in, pri_filename.c_str());
    RSA* rsa = PEM_read_bio_RSAPrivateKey(in, NULL, NULL, NULL);
    BIO_free(in);

    if (rsa == NULL) {
        std::cout << "PEM_read_bio_RSAPrivateKey failed" << std::endl;
        return std::vector<char>();
    }
    unsigned int size = RSA_size(rsa);
    std::vector<char> sign;
    sign.resize(size);

    int ret =
        RSA_sign(NID_md5, (const unsigned char*)message.c_str(),
                 message.length(), (unsigned char*)sign.data(), &size, rsa);
    RSA_free(rsa);
    if (ret != 1) {
        std::cout << "RSA_sign failed" << std::endl;
        return std::vector<char>();
    }
    return sign;
}

// 通过公钥文件验证签名
bool VerifyRsaSignByFile(char* sign, uint32_t sign_len,
                         const std::string& pub_filename,
                         const std::string& verify_str) {
    OpenSSL_add_all_algorithms();
    BIO* in = BIO_new(BIO_s_file());
    if (in == NULL) {
        std::cout << "BIO_new failed" << std::endl;
        return false;
    }

    BIO_read_filename(in, pub_filename.c_str());

    RSA* rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);

    if (rsa == NULL) {
        std::cout << "PEM_read_bio_RSA_PUBKEY failed" << std::endl;
        return false;
    }
    BIO_free(in);

    int ret =
        RSA_verify(NID_md5, (const unsigned char*)verify_str.c_str(),
                   verify_str.length(), (unsigned char*)sign, sign_len, rsa);
    RSA_free(rsa);
    if (ret != 1) {
        std::cout << "RSA_verify failed" << std::endl;
        return false;
    }
    return true;
}

八、openssl私钥生成签名,公钥验证签名(私钥和公钥通过字符串传进去)

// 通过私钥字符串生成签名
std::vector<char> GenerateRsaSignByString(const std::string& message,
                                          const std::string& prikey) {
    OpenSSL_add_all_algorithms();
    BIO* in = BIO_new_mem_buf((void*)prikey.c_str(), -1);
    if (in == NULL) {
        std::cout << "BIO_new_mem_buf failed" << std::endl;
        return std::vector<char>();
    }

    RSA* rsa = PEM_read_bio_RSAPrivateKey(in, NULL, NULL, NULL);
    BIO_free(in);

    if (rsa == NULL) {
        std::cout << "PEM_read_bio_RSAPrivateKey failed" << std::endl;
        return std::vector<char>();
    }
    unsigned int size = RSA_size(rsa);
    std::vector<char> sign;
    sign.resize(size);

    int ret =
        RSA_sign(NID_md5, (const unsigned char*)message.c_str(),
                 message.length(), (unsigned char*)sign.data(), &size, rsa);
    RSA_free(rsa);
    if (ret != 1) {
        std::cout << "RSA_sign failed" << std::endl;
        return std::vector<char>();
    }
    return sign;
}

// 通过公钥字符串验证签名
bool VerifyRsaSignByString(char* sign, uint32_t sign_len,
                           const std::string& pubkey,
                           const std::string& verify_str) {
    BIO* in = BIO_new_mem_buf((void*)pubkey.c_str(), -1);
    if (in == NULL) {
        std::cout << "BIO_new_mem_buf failed" << std::endl;
        return false;
    }

    RSA* rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
    BIO_free(in);

    if (rsa == NULL) {
        std::cout << "PEM_read_bio_RSA_PUBKEY failed" << std::endl;
        return false;
    }

    int ret =
        RSA_verify(NID_md5, (const unsigned char*)verify_str.c_str(),
                   verify_str.length(), (unsigned char*)sign, sign_len, rsa);
    RSA_free(rsa);
    if (ret != 1) {
        std::cout << "RSA_verify failed" << std::endl;
        return false;
    }
    return true;
}

九、全部代码下载

https://github.com/yangpan4485/openssl_rsa

  • 7
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
OpenSSL是一个开源的加密库,它提供了RSA加密解密签名和验签的功能。 对于RSA加密解密,我们可以使用OpenSSL提供的命令行工具或者API来实现使用命令行工具,我们可以通过以下命令进行RSA加密openssl rsautl -encrypt -in <input file> -out <output file> -inkey <public key file> -pubin 其中,<input file>是要加密的文件,<output file>是加密后的文件,<public key file>是存储公钥的文件,-pubin参数表示输入的是公钥使用命令行工具,我们可以通过以下命令进行RSA解密openssl rsautl -decrypt -in <input file> -out <output file> -inkey <private key file> 其中,<input file>是要解密的文件,<output file>是解密后的文件,<private key file>是存储私钥的文件。 对于RSA签名和验签,我们可以使用以下命令进行签名openssl rsautl -sign -in <input file> -out <output file> -inkey <private key file> 其中,<input file>是要签名的文件,<output file>是签名后的文件,<private key file>是存储私钥的文件。 使用以下命令进行验签: openssl rsautl -verify -in <input file> -out <output file> -inkey <public key file> -pubin 其中,<input file>是要验签的文件,<output file>是验签后的文件,<public key file>是存储公钥的文件,-pubin参数表示输入的是公钥使用OpenSSL的API进行RSA加密解密签名和验签的操作也是类似的,我们可以通过调用相应的函数来实现。需要注意的是,API的使用需要在代码中显式引入OpenSSL的头文件和链接OpenSSL的库文件。 总之,OpenSSL提供了便捷的工具和API来实现RSA加密解密签名和验签的功能,无论是命令行工具还是API,都可以选择合适的方式进行操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值