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虚拟机中的22个重难点(推荐0

    作为程序员必须掌握的Java虚拟机中的22个重难点攻略 Java虚拟机(JVM)是Java语言的核心,作为程序员必须深入了解JVM的原理和机制。本攻略介绍了JVM中的22个重难点,帮助程序员深入了解JVM并掌握JVM原理和调优技巧。 1. JVM 总论 JVM是Java的运行环境,它主要由类加载器、运行时数据区、执行引擎、本地接口、本地方法库和垃圾回收器组成…

    Java 2023年5月23日
    00
  • java DateUtil工具类时间戳类型转换详解

    Java DateUtil工具类时间戳类型转换详解 1. 什么是时间戳? 时间戳(Timestamp)是指格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。感性地理解,时间戳是用来表示一个时间点的数字,可以用于在不同的时间、时区、地点下定位和比较时间。 2. 如何在Java中使用时间戳? Java中可以使用Date、Calendar类来表…

    Java 2023年5月20日
    00
  • 详解堆排序算法原理及Java版的代码实现

    下面就是详解堆排序算法原理及Java版的代码实现的完整攻略。 堆排序算法原理 堆排序是一种基于完全二叉树的排序算法,它分为两个主要步骤:建堆和排序。其中建堆是将一个无序的数组调整成堆的过程,排序则是将堆中数据按照从小到大或从大到小的顺序进行排序的过程。 建堆过程中,首先需要从最后一个非叶子节点开始调整,保证整个数组满足堆的性质。若此处节点的值比它的子节点小,…

    Java 2023年5月19日
    00
  • 详解SpringMVC中的异常处理机制

    详解SpringMVC中的异常处理机制 在SpringMVC中,异常处理是一个非常重要的话题。在Web应用程序中,异常是不可避免的,因此我们需要一种机制来处理它们。本文将详细讲解SpringMVC中的异常处理机制,包括如何定义异常处理器、如何处理异常、如何返回异常信息等。 定义异常处理器 在SpringMVC中,我们可以使用@ControllerAdvice…

    Java 2023年5月18日
    00
  • java使用Hex编码解码实现Aes加密解密功能示例

    下面就来详细讲解”java使用Hex编码解码实现Aes加密解密功能示例”的完整攻略。 简介 在现代加密算法中,AES是目前最常用的对称加密算法,其加密解密速度快,安全性高,在实际应用中得到了广泛的应用。而Hex编码是将二进制转化为可读的十六进制字符表示的编码方式,用于数据传输或者存储。本文将介绍如何通过java使用Hex编码解码实现AES加密解密功能,该方法…

    Java 2023年5月20日
    00
  • Spring Boot jpa Service层代码实例

    下面我将详细讲解“Spring Boot jpa Service层代码实例”的完整攻略。 什么是Spring Boot jpa Service层 Spring Boot是一个快速开发的框架,它可以轻松地构建基于Spring框架的Web应用程序。而JPA(Java Persistence API)是一种Java EE标准API,用于管理Java对象到关系数据库…

    Java 2023年5月20日
    00
  • Java超详细教你写一个学籍管理系统案例

    Java超详细教你写一个学籍管理系统案例攻略 本文将介绍如何用Java语言编写一个学籍管理系统,包括如何设计数据库、如何实现登录、管理学生信息等功能。 设计数据库 首先,我们需要设计数据库表格。在本案例中,我们需要设计两个表格:学生表和用户表。学生表存储学生的基本信息,如学号、姓名、性别、年龄、所在班级、联系方式等。用户表存储管理员的用户名和密码。 实际上,…

    Java 2023年5月24日
    00
  • Java多线程常见案例分析线程池与单例模式及阻塞队列

    Java多线程常见案例分析线程池与单例模式及阻塞队列攻略 什么是多线程? 在计算机科学中,多线程(英语:Multithreading)指的是同时运行多个线程执行不同的任务。在线程中,单个处理器(或核心)会执行多个并发执行的任务。这是在现代操作系统中实现并发的一种方式。 什么是线程池? 线程池是预先实例化一定数量的线程,并在它们启动时将它们放入池中。每个任务都…

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