首页 > 其他分享 >使用 openssl 进行 RSA/ECB/PKCS1PADDING 加解密

使用 openssl 进行 RSA/ECB/PKCS1PADDING 加解密

时间:2024-03-19 22:33:34浏览次数:27  
标签:PKEY ECB bio 加解密 RSA PKCS1PADDING Cipher EVP new

使用java进行 RSA/ECB/PKCS1PADDING 是非常方便的,例如下面的示例

    public static String publicDecrypt(PublicKey publicKey,String encrypted) throws Exception{
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE,publicKey);
        byte[] data = cipher.doFinal(Base64.getDecoder().decode(encrypted.getBytes(StandardCharsets.UTF_8)));
        return new String(data);
    }

    public static String publicEncrypt(PublicKey publicKey,String encrypted) throws Exception{
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE,publicKey);
        byte[] data = cipher.doFinal(encrypted.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(data);
    }
    public static String privateEncrypt(PrivateKey privateKey,String toEncrypt) throws Exception{
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE,privateKey);
        byte[] data = cipher.doFinal(toEncrypt.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(data);
    }

    public static String privateDecrypt(PrivateKey privateKey,String toEncrypt) throws Exception{
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE,privateKey);
        byte[] data = cipher.doFinal(Base64.getDecoder().decode(toEncrypt.getBytes(StandardCharsets.UTF_8)));
        return new String(data);
    }

公钥加密的内容用私钥解密,私钥加密的内容用公钥解密。(严格来说,私钥加密的另外一种名称是“签名”)
使用 C/C++ 来实现的时候,没有java那么方便,下面是低版本openssl api的调用示范

#include<openssl/pem.h>
#include<openssl/rsa.h>
#include<openssl/bio.h>
...
    BIO* keybio = BIO_new_mem_buf(key.c_str(), (int)key.size());
    if (!keybio)
    {
        spdlog::error("new bio failed");
        return ;
    }
    RSA* rsa = PEM_read_bio_RSAPrivateKey(keybio, NULL, NULL, NULL);
    if (!rsa)
    {
        return ;
    }
    spdlog::info("rsa: {} ", fmt::ptr(rsa));
    uint8_t buffer[2048];
    int ret = RSA_private_encrypt((int)plaintext.size(), (const unsigned char*)plaintext.c_str(), buffer, rsa, RSA_PKCS1_PADDING);
    if (ret > 0)
    {
        std::string result = Base64Encode(buffer, ret);
        spdlog::info("encrypted:\n{}", result);
    }
    RSA_free(rsa);
...

其中,key是 pem 格式的字符串。上面的内容是使用私钥进行加密的例子。
大致的流程是使用 pem 格式的密钥,创建BIO对象,使用BIO对象创建密钥对象,使用密钥对象进行加密或者解密。
相应的,我们可以总结出以下内容

  • 私钥加密 PEM_read_bio_RSAPrivateKey,RSA_private_encrypt
  • 私钥解密 PEM_read_bio_RSAPrivateKey,RSA_private_decrypt
  • 公钥加密 PEM_read_bio_RSAPublicKey, RSA_public_encrypt
  • 公钥解密 PEM_read_bio_RSAPublicKey, RSA_public_decrypt
    以上4种接口在低版本的 openssl 上使用是没有问题的,但是在 openssl 3.0 齐,以上接口标记为弃用状态了。
    下面是高版本 openssl 使用公钥解密的例子
#include<openssl/pem.h>
#include<openssl/rsa.h>
#include<openssl/bio.h>
#include<openssl/evp.h>
#include<memory>
...
    const unsigned char* in;
    size_t inlen;
    std::string pemKey;
    //这里假设我们通过一系列操作得到了要加密的内容和pem格式的密钥....
    std::vector<unsigned char> out;
    int ret = 0;
    std::shared_ptr<BIO> keybio(BIO_new_mem_buf(pemKey.c_str(), (int)pemKey.size()), BIO_free);
    std::shared_ptr<EVP_PKEY> key(PEM_read_bio_PUBKEY(keybio.get(), nullptr, nullptr, nullptr), EVP_PKEY_free);
    std::shared_ptr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(key.get(), nullptr), EVP_PKEY_CTX_free);
    EVP_PKEY_encrypt_init(ctx.get());
    EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PADDING);
    size_t outlen = 0;
    ret = EVP_PKEY_encrypt(ctx.get(), nullptr, &outlen, in, inlen);
    out.resize(outlen);
    ret = EVP_PKEY_encrypt(ctx.get(), out.data(), &outlen, in, inlen);

大致步骤如下

  1. 通过pem格式的密钥创建一个BIO对象 BIO_new_mem_buf
  2. 通过BIO对象创建一个EVP_PKEY对象 PEM_read_bio_PUBKEY
  3. 通过EVP_PKEY创建一个EVP_PKEY_CTX对象 EVP_PKEY_CTX_new
  4. 通过EVP_PKEY_encrypt_init声明需要进行公钥加密
  5. 通过EVP_PKEY_encrypt进行加密操作

高版本 openssl 的接口替换如下

  • 私钥加密 PEM_read_bio_PrivateKey,EVP_PKEY_CTX_new,EVP_PKEY_sign_init,EVP_PKEY_sign
  • 私钥解密 PEM_read_bio_PrivateKey,EVP_PKEY_CTX_new,EVP_PKEY_decrypt_init,EVP_PKEY_decrypt
  • 公钥加密 PEM_read_bio_PUBKEY, EVP_PKEY_CTX_new,EVP_PKEY_encrypt_init,EVP_PKEY_encrypt
  • 公钥解密 PEM_read_bio_PUBKEY, EVP_PKEY_CTX_new,EVP_PKEY_verify_recover_init,EVP_PKEY_verify_recover

标签:PKEY,ECB,bio,加解密,RSA,PKCS1PADDING,Cipher,EVP,new
From: https://www.cnblogs.com/SupperMary/p/18084137

相关文章

  • 接口RSA加解密参考
    后端依赖当然,这里也可以自行实现,获取使用rsa+aes组合的方案来实现。<dependency><groupId>cn.shuibo</groupId><artifactId>rsa-encrypt-body-spring-boot</artifactId><version>1.0.1.RELEASE</version></dependency>示例@Spring......
  • AES 加解密(前后端)
    AES加解密(前后端)加密前端加密:aesEncrypt(plainText:string,key:string){constkey=CryptoJS.enc.Latin1.parse(key);constiv=CryptoJS.enc.Latin1.parse('1234567890123456');constencrypted=CryptoJS.AES.encrypt(plainText,key,{......
  • 一款针对加解密综合利用后渗透工具-DecryptTools
    0x01前言为什么会写这一款综合加解密工具,因为在很多比赛如果算拿下靶标不仅需要获取服务器权限还需要登录网站后台这时候很多系统要么数据库连接字符串加密,要么登陆用户加密而这款工具就是为了解决问题。加解密功能:该工具不仅有解密还提供多种加密方式。配置文件信息功......
  • mPaas抓包分析和数据加解密
    mPaaS是阿里研发的一个移动开发平台,其中移动网关服务(MobileGatewayService,简称MGS)作为mPaas最重要的组件之一,连接了移动客户端与服务端,简化了移动端与服务端的数据协议和通讯协议,从而能够显著提升开发效率和网络通讯效率。通过RPC组件进行网络请求,并且可以设置拦截器拦截请求......
  • JavaScript逆向之有道翻译加解密全过程解析
    本篇文章用于解析有道翻译中的加解密全过程url:https://fanyi.youdao.com/index.html#/加密访问网址,输入框中随便输入一个英文单词,查看触发流量包,只看Fetch/XHR类型的。这里主要关注webtranslate的这条,请求参数和响应数据都是有加密的,主要了解其的加解密逻辑。根据url定位......
  • 大语言模型(LLM)安全性测试SecBench平台洞察分析
     摘要业界首个网络安全大模型评测平台SecBench正式发布(2024-1-19),主要解决开源大模型在网络安全应用中安全能力的评估难题,旨在为大模型在安全领域的落地应用选择基座模型提供参考,加速大模型落地进程。同时,通过建设安全大模型评测基准,为安全大模型研发提供公平、公正、客观、全......
  • Java RSA 加解密工具类,直接用
    importorg.junit.Test;importjavax.crypto.Cipher;importjavax.crypto.NoSuchPaddingException;importjava.io.ByteArrayOutputStream;importjava.nio.charset.Charset;importjava.nio.charset.StandardCharsets;importjava.security.*;importjava.security.i......
  • jmeter_BeanShell脚本&通过BeanShell进行加解密方法
    BeanShell脚本BeanShell简介:BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法;BeanShell是一种松散类型的脚本语言;BeanShell是用Java写成的,一个小型的、免费的、可以下载、嵌入式的Java源代码解释器,具有对象脚本的特性;BeanShell可以执行标准J......
  • 基于chaos混沌的彩色图像加解密系统matlab仿真
    1.算法运行效果图预览 2.算法运行软件版本matlab2022a 3.算法理论概述      基于混沌(Chaos)的彩色图像加解密系统是一种新型的图像加密技术,它利用了混沌理论的特性来提供高度安全的图像加密。下面将详细介绍这种系统的原理、数学公式和实现过程。 3.1混沌理论......
  • 【SpringBootStarter】自定义全局加解密组件
    【SpringBootStarter】目的了解SpringBootStarter相关概念以及开发流程实现自定义SpringBootStarter(全局加解密)了解测试流程优化最终引用的效果:<dependency><groupId>com.xbhog</groupId><artifactId>globalValidation-spring-boot-starter</artifactId>......