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中,发送端和接收端都需要获取密钥对中的公钥或私钥。为了简便起见,这里省略了从文件、数据库等外部存储中获取密钥的部分。

阅读剩余 69%

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

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

相关文章

  • 详解SpringCloud Gateway之过滤器GatewayFilter

    下面是Spring Cloud Gateway过滤器GatewayFilter的详解攻略: 什么是Gateway Filter Spring Cloud Gateway 的过滤器(Filters)提供了许多内置的功能,包括路由转发、限流、安全、监控等。Gateway Filter 是一个基本的工作单元,它由若干个有顺序的 GatewayFilter组成。每个…

    Java 2023年5月20日
    00
  • java常用Lambda表达式使用场景源码示例

    Java常用Lambda表达式使用场景源码示例 什么是Lambda表达式? Lambda表达式是Java 8引入的新特性之一,它是一个匿名函数,可以传递到函数式接口中使用。Lambda表达式提供了一个简单而强大的语法来处理集合数据,比传统的循环语句更加简洁易懂。 Lambda表达式的语法格式为:(parameters) -> expression 或 …

    Java 2023年5月26日
    00
  • Fixie.js 自动填充内容的插件

    Fixie.js 是一个用于自动填充表单内容的 JavaScript 插件,可以自动填充表单、日期、时间等多种类型的数据。下面是使用 Fixie.js 的详细攻略: 第一步:引入 Fixie.js 将 Fixie.js 文件下载到本地,并在 HTML 中引入该文件,代码如下: <script src="path/to/fixie.js&quo…

    Java 2023年6月15日
    00
  • Java数据结构及算法实例:冒泡排序 Bubble Sort

    Java数据结构及算法实例:冒泡排序 Bubble Sort 冒泡排序概念 冒泡排序算法是通过不断地比较相邻两个元素,把较大的元素交换到后面,较小的元素交换到前面,以此类推,直到整个数组有序的排序算法。 冒泡排序基本思路 冒泡排序的基本思路是不断地比较相邻的元素,如果前面的元素比后面的元素大,则交换这两个元素。这样,每一次都可以将最大的元素“浮”到最后面。由…

    Java 2023年5月19日
    00
  • 排序算法图解之Java归并排序的实现

    我很乐意为您详细讲解“排序算法图解之Java归并排序的实现”的完整攻略。 算法概述 归并排序(Merge Sort)是一种比较常见的排序算法,它采用了分治策略,将要排序的数组分成若干个子问题,先解决子问题,再合并子问题的结果得到最终结果。 具体实现,就是将数组不断地拆分成两个子数组,直到子数组中只有一个元素,然后再将有序的子数组合并成一个大的有序数组。 实现…

    Java 2023年5月19日
    00
  • java异常处理的简单练习

    Java异常处理的简单练习攻略 在Java编程中,异常处理是一个至关重要的话题。当程序执行时出现错误时,如果我们不进行处理,程序就会崩溃,并输出一些不必要的错误信息。因此,我们需要使用Java异常处理机制来捕获这些异常,并采取适当的行动来处理它们。 简单的Java异常处理练习题 现在,我们来考虑一个简单的Java异常处理练习题。假设我们要编写一个程序,从用户…

    Java 2023年5月27日
    00
  • SpringBoot中实现接收文件和对象

    首先,我们需要添加SpringBoot Web和Multipart依赖,其pom.xml配置如下: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactI…

    Java 2023年6月3日
    00
  • 深入理解Spring Cache框架

    关于“深入理解Spring Cache框架”的完整攻略,我会从以下几个方面进行详细讲解: Spring Cache框架的概念及应用场景 Spring Cache框架的核心组件 Spring Cache框架的使用方法和注意事项 两条示例,演示Spring Cache的具体使用 1. Spring Cache框架的概念及应用场景 Spring Cache框架是S…

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