Java编程实现非对称加密的方法详解

Java编程实现非对称加密的方法详解

非对称加密算法需要公钥和私钥。公钥可以对任意一个字符串进行加密,但只能用对应的私钥进行解密;私钥可以对任何一个字符串进行解密,但是只有对应的公钥能够进行加密。

生成密钥对

Java提供了多种非对称加密算法,比如RSA算法。使用Java生成RSA密钥对的过程如下:

import java.security.KeyPair;
import java.security.KeyPairGenerator;

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048); // 初始化密钥长度为2048位
KeyPair keyPair = keyPairGenerator.genKeyPair();

byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();

实例化 KeyPairGenerator 对象可以通过其提供者或者算法名称实现,这里我们使用 RSA 算法,密钥长度为2048位。调用 genKeyPair 方法就可以获得 KeyPair 对象。通过 getPublic 和 getPrivate 方法可以获取 PublicKey 和 PrivateKey,再使用 getEncoded 方法转换成二进制格式的字节串,方便存储或传输。

加密

使用公钥加密一个字符串:

import java.security.PublicKey;
import javax.crypto.Cipher;

String plainText = "Hello, world.";
byte[] publicKeyBytes = ...; // 获取公钥的二进制格式字节串
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes));

Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));

实例化 PublicKey 对象需要通过 KeyFactory 和 X509EncodedKeySpec 进行转换,在 Cipher 中使用公钥和 ENCRYPT_MODE 初始化后,调用 doFinal 方法将明文转换为密文(字节数组)。

解密

使用私钥解密上一步所得到的密文:

import java.security.PrivateKey;

byte[] privateKeyBytes = ...; // 获取私钥的二进制格式字节串
PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));

cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
String plainText = new String(decryptedBytes, "UTF-8");

同样地,实例化 PrivateKey 对象需要通过 KeyFactory 和 PKCS8EncodedKeySpec 进行转换,在 Cipher 中使用私钥和 DECRYPT_MODE 初始化后,调用 doFinal 方法将密文转换为明文。

示例说明

示例 1:加密字符串并进行解密

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import javax.crypto.Cipher;

public class AsymmetricEncryptionExample {
    public static void main(String[] args) throws Exception {
        String plainText = "Hello, world.";

        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048); // 初始化密钥长度为2048位
        KeyPair keyPair = keyPairGenerator.genKeyPair();

        byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
        byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();

        PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes));
        PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));

        Cipher cipher = Cipher.getInstance("RSA");

        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
        System.out.println("Encrypted: " + new String(encryptedBytes, "UTF-8"));

        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        String decryptedText = new String(decryptedBytes, "UTF-8");
        System.out.println("Decrypted: " + decryptedText);
    }
}

输出:

Encrypted: ?0Mf???F???n@G?P?4?p??jd?g?z$?F?5?Xv?

Decrypted: Hello, world.

示例 2:使用公钥加密并传输密文,使用私钥解密

// 发送端
public class AsymmetricEncryptionExample {
    public static void main(String[] args) throws Exception {
        String plainText = "Hello, world.";

        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048); // 初始化密钥长度为2048位
        KeyPair keyPair = keyPairGenerator.genKeyPair();

        byte[] publicKeyBytes = keyPair.getPublic().getEncoded();

        PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes));

        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));

        System.out.println("Encrypted: " + new String(encryptedBytes, "UTF-8"));

        // 假设将 encryptedBytes 转换成Base64编码的字符串,传给接收端
    }
}

// 接收端
public class AsymmetricEncryptionExample {
    public static void main(String[] args) throws Exception {
        byte[] encryptedBytes = ...; // 假设获取到 Base64 编码的密文,解码成字节数组
        byte[] privateKeyBytes = ...; // 获取私钥的二进制格式字节串

        PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));

        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        String decryptedText = new String(decryptedBytes, "UTF-8");
        System.out.println("Decrypted: " + decryptedText);
    }
}

输出:

Decrypted: Hello, world.

在示例2中,发送端和接收端都需要获取密钥对中的公钥或私钥。为了简便起见,这里省略了从文件、数据库等外部存储中获取密钥的部分。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java编程实现非对称加密的方法详解 - Python技术站

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

相关文章

  • Java Apache Commons报错“ZipException”的原因与解决方法

    “ZipException”是Java的Apache Commons类库中的一个异常,通常由以下原因之一引起: 压缩文件错误:如果压缩文件存在错误,则可能会出现此异常。例如,可能会使用错误的压缩文件格式或压缩文件已损坏。 文件路径错误:如果文件路径错误,则可能会出现此异常。例如,可能会使用错误的文件路径或文件不存在。 以下是两个实例: 例1 如果压缩文件存在…

    Java 2023年5月5日
    00
  • java — 线程(一)

    线程与进程 进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。线程:是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多…

    Java 2023年4月18日
    00
  • Java中的空指针异常如何避免?

    Java中的空指针异常(NullPointerException)是Java中最常见的异常之一。它表示当尝试使用一个空对象时,程序出现了异常。这个空对象可能是一个没有被实例化的对象、一个已经被释放的对象或者一个 null 对象。在 Java 中,可以通过以下方式来避免空指针异常。 1. 对象是否为空的判断 在使用对象之前一定要判断是否为空,只有在它不为空的情…

    Java 2023年4月27日
    00
  • Java ArrayList源码深入分析

    Java ArrayList源码深入分析 概述 Java中的ArrayList是最基础的动态数组实现,是Java集合框架中的重要组成部分。本文将分析ArrayList源码,通过详细的代码解析和实例说明,深入分析ArrayList的内部实现原理。 前置知识 在深入分析ArrayList源码之前,需要具备以下基础知识: Java集合框架的基本概念和应用场景 数组…

    Java 2023年5月26日
    00
  • Springboot 1.5.7整合Kafka-client代码示例

    下面我来详细讲解 SpringBoot 1.5.7 整合 Kafka-Client 的完整攻略,包括以下两条代码示例: 第一步:构建SpringBoot项目 首先,我们需要在本地构建一个 SpringBoot 项目。下面是示例代码: $ mkdir springboot-kafka-demo $ cd springboot-kafka-demo $ mvn …

    Java 2023年5月20日
    00
  • 弱引用的作用是什么?

    弱引用(Weak Reference)是 Python 语言中的一个重要概念,它是一种特殊的对象引用,与常规引用(Strong Reference)不同,它不会阻止被引用的对象被垃圾回收器回收,主要用于解决循环引用的问题。下面是弱引用的使用攻略。 弱引用的作用 在 Python 中,一般情况下会使用强引用来引用一个对象,这会使得该对象的引用计数加 1。当强引…

    Java 2023年5月10日
    00
  • JAVA中SSM框架的搭建实现CRUD的方法

    JAVA中SSM框架的搭建实现CRUD操作可以分为以下几个步骤: 1. 搭建环境 首先,我们需要安装必要的软件和工具: JDK Maven Eclipse或IntelliJ IDEA Tomcat MySQL 并配置环境变量和路径。安装完成后,在Eclipse或IntelliJ IDEA中创建一个新的Maven项目。 2. 添加依赖 在pom.xml文件中,…

    Java 2023年6月15日
    00
  • Java实现一个简易版的多级菜单功能

    Java实现一个简易版的多级菜单功能 思路概述 实现一个简易版的多级菜单功能,需要用到递归和HashMap的知识。我们可以将菜单项存储在HashMap中,其中键为菜单名称,值为对应菜单的子菜单。如果一个菜单项没有子菜单,我们将其子菜单设置为null。 通过递归的方式,我们可以深度遍历每个菜单项,并打印出每个菜单项的名称。如果该菜单项还有子菜单,我们则继续递归…

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