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日

相关文章

  • java实现文本框和文本区的输入输出

    下面我将详细讲解“Java实现文本框和文本区的输入输出”的完整攻略。 目录 实现文本框的输入输出 如果只需要获取文本框的文本内容 如果需要监听文本框的事件 实现文本区的输入输出 获取文本区的文本内容 设置文本区的文本内容 如果需要监听文本区的事件 实现文本框的输入输出 如果只需要获取文本框的文本内容 使用JTextField类可以实现文本框,可以通过getT…

    Java 2023年5月19日
    00
  • Java的Struts框架报错“ActionTokenException”的原因与解决办法

    当使用Java的Struts框架时,可能会遇到“MappingNotFoundException”错误。这个错误通常由以下原因之一起: 配置错误:如果配置文件中没有正确配置,则可能会现此错误。在这种情况下检查文件以解决此问题。 URL错误:如果URL不正确,则可能会出现此错误。在这种情况下,需要检查URL以解决此问题。 以下是两个实例: 例 1 如果配置文件…

    Java 2023年5月5日
    00
  • 关于Java实现HttpServer模拟前端接口调用

    关于Java实现HttpServer模拟前端接口调用,可以按照以下步骤进行: 一、实现HttpServer 1.引入HttpServer依赖,例如使用Jetty <dependencies> <dependency> <groupId>org.eclipse.jetty</groupId> <artifa…

    Java 2023年5月26日
    00
  • Java垃圾回收器的作用是什么?

    下面是详细讲解Java垃圾回收器的作用的完整使用攻略: 1. 垃圾回收器的作用 Java垃圾回收器的主要作用就是自动管理Java程序运行时的内存空间,在程序运行过程中及时释放不再使用的内存空间,提高程序的运行效率和稳定性。 当Java程序在运行时需要占用一定内存空间,当内存空间不够时,Java虚拟机就会启动垃圾回收器,自动回收无用的内存,以便腾出更多的空间给…

    Java 2023年5月11日
    00
  • jsp分页显示完整实例

    下面就来详细讲解一下“jsp分页显示完整实例”的攻略。 什么是分页显示? 分页显示是指将大量数据分开展示,并通过页面的控件使用户可以翻页操作,进行查看。 为什么需要分页显示? 如果展示的数据量过大,会导致页面加载速度变慢,甚至使页面崩溃。另外,用户在查看数据时,如果没有分页功能,会使得他们无法方便地找到所需数据。 实现分页显示的方法 实现分页显示有多种方法,…

    Java 2023年6月15日
    00
  • java 创建自定义数组

    下面我将为您详细讲解Java创建自定义数组的完整攻略。 创建自定义数组 Java中可以通过定义一个类来自定义一个数组。定义一个数组需要完成以下步骤: 定义数组类 在数组类中定义数组元素的类型、数组长度和下标索引 实现获取、设置和遍历数组元素的方法 定义数组类 定义自定义数组类需要使用Java的面向对象编程思想。一个数组可以看做是一个对象,需要自定义一个数组类…

    Java 2023年5月26日
    00
  • Java基础之代码死循环详解

    Java基础之代码死循环详解 简介 代码死循环是指在程序运行过程中,因为某些原因造成程序不停地重复执行某一段代码的现象。死循环通常是因为程序设计不合理或者编写错误所导致的,如果长时间不会自动退出,会造成计算机死机或者卡死。代码死循环是编写程序时需要避免的错误。 常见死循环 for循环死循环 for(int i=0; i>=0; i++){ System…

    Java 2023年5月20日
    00
  • java实现电话本管理系统

    Java实现电话本管理系统 1. 简介 电话本管理系统是一款方便用户管理联系人信息的工具,可以添加、删除、修改和查看联系人信息。本文将会介绍使用Java来开发这样一款电话本管理系统的完整攻略。 2. 技术选择 编程语言:Java 开发环境:Eclipse 数据库:MySQL Web框架:Spring Boot 前端框架:Vue.js 项目构建工具:Maven…

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