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日

相关文章

  • springmvc fastjson 反序列化时间格式化方法(推荐)

    SpringMVC Fastjson 反序列化时间格式化方法 1. 什么是Fastjson? Fastjson是一个Java语言编写的高性能JSON处理器,它可以将Java对象转换为JSON格式的字符串,也可以将JSON格式的字符串转换为Java对象。Fastjson具有快速、简单、灵活等特点,是目前Java开发中最流行的JSON处理器之一。 2. Spri…

    Java 2023年5月18日
    00
  • java构造函数示例(构造方法)

    下面我来详细讲解一下“Java构造函数示例(构造方法)”的完整攻略。 1. 构造函数简介 构造函数是一种特殊的方法,用于创建并初始化对象。它的特殊之处在于:在创建对象时会自动调用构造函数进行初始化操作,通常用于给对象的属性进行赋值。 2. 构造函数的定义和使用 构造函数的定义格式与普通方法相似,但是没有返回值类型,也没有void关键字。下面是构造函数的示例代…

    Java 2023年5月20日
    00
  • Java基础学习之关键字和变量数据类型的那些事

    Java基础学习之关键字和变量数据类型的那些事 一、关键字 Java中有一些单词是具有特殊含义的,这些单词被称为关键字。我们不能将关键字用作标识符(变量名、方法名等)。Java中共有50个关键字,其中一部分已经不再使用,比如goto、const等。下面列出常用的关键字: abstract default if private this boolean do …

    Java 2023年5月20日
    00
  • Mybatis-Spring源码分析图解

    下面是详细的“Mybatis-Spring源码分析图解”攻略。 1. Mybatis-Spring简介 Mybatis-Spring是Mybatis和Spring框架结合的一个组件集,简化了Mybatis和Spring框架的整合过程,为使用者提供了方便快捷的数据库持久层开发手段。使用Mybatis-Spring可以有效将Mybatis和Spring框架解耦,…

    Java 2023年5月20日
    00
  • Eclipse下编写java程序突然不会自动生成R.java文件和包的解决办法

    下面是详细讲解“Eclipse下编写java程序突然不会自动生成R.java文件和包的解决办法”的完整攻略。 问题描述 在使用Eclipse编写Java程序时,可能会遇到不会自动生成R.java文件和包的情况,这会导致在项目中使用资源文件时出现问题。 解决步骤 步骤一:检查项目配置 首先,需要检查项目的配置是否正确。可以按照以下步骤操作: 在Eclipse中…

    Java 2023年5月26日
    00
  • 一篇文章读懂Java哈希与一致性哈希算法

    一篇文章读懂Java哈希与一致性哈希算法 1. 哈希算法基础 在计算机科学中,哈希算法是将任意长度的消息映射到固定长度的摘要 (或称哈希值) 的函数,也就是根据某种规则,将任意数据映射到指定大小范围的数值上,一般用于唯一性标识、数据校验等场景。 Java提供了多种哈希算法,比如MD5、SHA1、SHA256等,这些哈希算法的实现已经被封装在Java的类库中的…

    Java 2023年5月19日
    00
  • Android开发学习路线的七大阶段

    当你开始学习Android开发时,为了使你的学习变得更具有结构性、更有效率,你可以将你的学习路线分为7个阶段,具体如下: 阶段1:入门 在这个阶段,你需要了解一些基础的概念和原理,例如Java语言基础、Android应用基础组件和Android Studio开发工具的使用。完成模拟器上的Hello World应用程序,并能够了解Android应用的基本结构和…

    Java 2023年6月15日
    00
  • Java连接mysql数据库代码实例程序

    这里提供的完整攻略将帮助大家编写Java连接mysql数据库的代码实例程序。 步骤一:下载并安装JDBC驱动程序 在使用Java连接mysql数据库之前,我们需要下载并安装mysql JDBC驱动程序。这里我们以mysql-connector-java-8.0.25.jar为例,在这个网页上下载mysql JDBC驱动程序:https://dev.mysql…

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