Java OpenSSL生成的RSA公私钥进行数据加解密详细介绍

针对“Java OpenSSL生成的RSA公私钥进行数据加解密详细介绍”的话题,以下是完整攻略的介绍:

一、概述

OpenSSL是一个开源的安全套接字层(SSL)实现库,能够实现多种安全协议,包括SSL和TLS。Java OpenSSL是使用Java编写的,利用OpenSSL库生成RSA公私钥,以及使用公私钥进行数据的加解密。

本文将详细介绍Java OpenSSL如何生成RSA公私钥,以及使用公私钥进行数据加解密。

二、生成RSA公私钥

通过以下命令在Linux环境下生成2048位密钥:

openssl genpkey -algorithm RSA -out private.key
openssl rsa -in private.key -pubout -out public.key

注:这里生成的公钥、私钥可以在Java和其他支持openssl密钥格式的语言中使用。

通过Java OpenSSL代码生成RSA公私钥:

import sun.security.x509.X500Name;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CertInfo;

import javax.security.auth.x500.X500Principal;
import java.io.*;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.*;

public class GenerateKeyPairUtil {

    private static final String keyAlg = "RSA";

    public static KeyPair generateRSAKeyPair(File publicKeyFile, File privateKeyFile) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, IOException, CertificateException, InvalidKeySpecException {
        SecureRandom secureRandom = new SecureRandom();
        KeyPairGenerator kpGen = KeyPairGenerator.getInstance(keyAlg, "BC");

        RSAKeyGenParameterSpec spec = new RSAKeyGenParameterSpec(2048, RSAKeyGenParameterSpec.F4);
        kpGen.initialize(spec, secureRandom);

        KeyPair keyPair = kpGen.generateKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey) keyPair.getPrivate();

        // 导出公钥
        X509Certificate cert = generateX509V3Cert(publicKey, privateKey);

        OutputStream pemPublicKey = new FileOutputStream(publicKeyFile);
        pemPublicKey.write("-----BEGIN PUBLIC KEY-----\n".getBytes());
        pemPublicKey.write(new String(org.bouncycastle.util.encoders.Base64.encode(cert.getEncoded())).getBytes());
        pemPublicKey.write("\n-----END PUBLIC KEY-----\n".getBytes());
        pemPublicKey.flush();
        pemPublicKey.close();

        // 导出私钥
        FileOutputStream fos = new FileOutputStream(privateKeyFile);
        fos.write("-----BEGIN PRIVATE KEY-----\n".getBytes());
        fos.write(new String(org.bouncycastle.util.encoders.Base64.encode(privateKey.getEncoded())).getBytes());
        fos.write("\n-----END PRIVATE KEY-----\n".getBytes());
        fos.flush();
        fos.close();

        return keyPair;
    }

    private static X509Certificate generateX509V3Cert(RSAPublicKey publicKey, RSAPrivateCrtKey privateKey) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException, IOException, CertificateEncodingException, CertificateException {
        X500Name x500Name = new X500Name(new X500Principal("CN=Java OpenSSL RSA Test").getName());

        BigInteger serialNumber = new BigInteger(64, new SecureRandom());
        long now = System.currentTimeMillis();
        X509CertInfo info = new X509CertInfo();
        info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
        info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(serialNumber));
        info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(x500Name));
        info.set(X509CertInfo.ISSUER, new CertificateIssuerName(x500Name));
        info.set(X509CertInfo.VALIDITY, new CertificateValidity(new Date(now), new Date(now + 365L * 24L * 60L * 60L * 1000L)));
        info.set(X509CertInfo.KEY, new CertificateX509Key(publicKey));
        info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(new AlgorithmId(AlgorithmId.sha256WithRSAEncryption_oid, AlgorithmId.rsaEncryption)));

        X509CertImpl cert = new X509CertImpl(info);
        cert.sign(privateKey, "SHA256withRSA");
        return cert;
    }

    public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, IOException, CertificateException, InvalidKeySpecException {
        KeyPair keyPair = GenerateKeyPairUtil.generateRSAKeyPair(new File("public.key"), new File("private.key"));

        System.out.println("Public key:\n" + keyPair.getPublic().toString() + "\n");
        System.out.println("Private key:\n" + keyPair.getPrivate().toString());
    }
}

在执行完上述代码后,在指定的目录下会生成名称为“public.key”和“private.key”的公钥和私钥文件。

三、RSA加解密

RSA是一种非对称加密算法,根据公钥加密,私钥解密。

  1. RSA公钥加密

RSA公钥加密示例:

import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.openssl.PEMWriter;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.StringWriter;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Security;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.X509EncodedKeySpec;

public class RSAEncryptUtil {

    static {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    }

    public static byte[] encrypt(byte[] data, String publicKeyFile) throws Exception {
        // 读取公钥
        PEMReader reader = new PEMReader(new FileReader(publicKeyFile));
        JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
        PublicKey publicKey = converter.getPublicKey((RSAPublicKey) reader.readObject());
        reader.close();

        Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BC");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);

        return cipher.doFinal(data);
    }

    public static void main(String[] args) throws Exception {
        // 待加密数据
        String data = "Hello, world!";

        // 加载RSA公钥
        String publicKeyFile = "public.key";

        // 加密
        byte[] encrypted = RSAEncryptUtil.encrypt(data.getBytes(), publicKeyFile);

        // 将加密后的数据进行Base64编码,方便传输
        String encryptedBase64 = new String(org.bouncycastle.util.encoders.Base64.encode(encrypted));

        System.out.println("加密前:" + data);
        System.out.println("加密后:" + encryptedBase64);
    }
}
  1. RSA私钥解密

RSA私钥解密示例:

import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;

import javax.crypto.Cipher;
import java.io.FileReader;
import java.security.PrivateKey;
import java.security.Security;
import java.security.interfaces.RSAPrivateCrtKey;

public class RSADecryptUtil {

    static {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    }

    public static byte[] decrypt(byte[] data, String privateKeyFile) throws Exception {
        // 读取私钥
        PEMReader reader = new PEMReader(new FileReader(privateKeyFile));
        JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
        PrivateKey privateKey = converter.getPrivateKey((RSAPrivateCrtKey) reader.readObject());
        reader.close();

        Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BC");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        return cipher.doFinal(data);
    }

    public static void main(String[] args) throws Exception {
        // 待解密数据
        String encryptedBase64 = "WbWSkZlwsP6QcCI1CksTZ2atyWrxFhq/f5PHj0tPchB+znmrldyF76Sp7k3SLx9STuL2T1Qzg1kXsg2TYiUoJNEcs9TJupf6834KvGgLit7aJHgQsd78/Hio6lZay8uSMMXGd7mF8EN1WVK9d5YjRmBFSxe1mwmowlzhtYS9IL8=";

        // 加载RSA私钥
        String privateKeyFile = "private.key";

        // 解密
        byte[] decrypted = RSADecryptUtil.decrypt(org.bouncycastle.util.encoders.Base64.decode(encryptedBase64.getBytes()), privateKeyFile);

        System.out.println("解密前:" + new String(decrypted));
        System.out.println("解密后:" + new String(decrypted));
    }
}

在上述示例中,给出了Java OpenSSL生成的RSA测试公私钥及其加解密的示例。这些示例需要依存Bouncy Castle库,应在自己的项目中将其添加到类路径中。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java OpenSSL生成的RSA公私钥进行数据加解密详细介绍 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • JSP+Ajax 添加、删除多选框

    下面是关于“JSP+Ajax 添加、删除多选框”的攻略。 什么是JSP+Ajax 添加、删除多选框 在 JSP 页面中,我们可以使用多选框来实现批量操作功能。但是,如果想要实现添加、删除选项的功能,通常需要使用 JavaScript 或 JQuery 等客户端脚本。这种方式需要刷新页面才能看到结果,用户体验不好。 而使用 Ajax 技术,则可以通过后台动态更…

    Java 2023年6月15日
    00
  • java单例五种实现模式解析

    Java单例五种实现模式解析 什么是单例模式? 单例模式是指一个类只能被实例化一次,并且全局都可以访问到这个实例。在实际开发中,很多情况下我们只需要一个实例,例如全局配置信息、日志管理等等,这时候使用单例模式可以节省系统资源,减少不必要的开销。 单例模式的特点 保证一个类只有一个实例。 提供一个访问该实例的全局入口。 不能被其他对象实例化。 五种实现模式 1…

    Java 2023年5月26日
    00
  • java jdbc连接mysql数据库实现增删改查操作

    Java JDBC连接MySQL数据库实现增删改查操作 简介 Java中的JDBC(Java Database Connectivity)是Java语言操作数据库的通用API,能够与各种关系型数据库进行交互。MySQL是一种流行的关系型数据库,在Java中使用JDBC连接MySQL数据库进行增删改查操作既方便又常用。 步骤 1. 准备工作 在使用JDBC连接…

    Java 2023年5月19日
    00
  • java实现二维数组转置的方法示例

    针对”java实现二维数组转置的方法示例”,我为您提供完整攻略如下: 一、题目分析 二维数组转置是将行和列的位置互换,即行变为列,列变为行,其基本原理是通过两层循环,依次交换每一个元素。 二、Java实现方法 Java实现二维数组转置可以按以下步骤进行: 1.定义原始的二维数组: 我们先定义原始的二维数组,一般可以通过随机生成数或者手动初始化等方法来实现。 …

    Java 2023年5月26日
    00
  • Java调用C++程序的实现方式

    Java调用C++程序的实现方式主要涉及两个方面:JNI和JNA。接下来,我将分别介绍这两种实现方式。 使用JNI实现Java调用C++程序 JNI是Java Native Interface的简称,是Java提供的一种本地方法调用的标准接口。它允许Java程序和本地代码(例如C++、C等)进行交互,并提供了一系列的API接口用于支持Java程序与本地代码的…

    Java 2023年5月19日
    00
  • 使用Java构造和解析Json数据的两种方法(详解一)

    使用Java构造和解析JSON数据的两种方法有:使用Java的JSONObject和JSONArray类和使用第三方库Gson。 使用Java的JSONObject和JSONArray类 在使用该方法前,需要先导入JSON库,例如org.json库。 构造JSON数据 使用JSONObject和JSONArray类可以方便地构造JSON数据。JSONObje…

    Java 2023年5月26日
    00
  • Java基于控制台界面实现ATM系统

    要实现“Java基于控制台界面实现ATM系统”,可以遵循以下步骤: 1. 设计功能模块 首先,需要明确ATM系统需要的功能模块,包括登录、查询余额、取款、转账、修改密码、退出等模块。可以用流程图或伪代码来描述这些功能模块的实现逻辑。 2. 实现代码 接下来,需要编写Java代码,来实现这些功能模块。可以先搭建好基本框架,然后以模块化的方式,逐步实现各个功能模…

    Java 2023年5月24日
    00
  • Java中的OpenJDK使用原理

    Java中的OpenJDK使用原理 OpenJDK是一个免费开源的Java开发工具包,由于其免费且开源的特性,越来越多的Java开发者开始使用OpenJDK,那么如何使用OpenJDK呢?下面是详细的使用攻略: 安装OpenJDK 在使用OpenJDK之前,需要先安装OpenJDK,下面以CentOS 7为例,介绍安装OpenJDK的方法(其他系统可以自行搜…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部