JAVA 做非对称加密(RSA)

Java中加密方式之非对称加密 它是由Whitfield Diffie和Martin Hellman在1976年发明的,是第一个公开披露的密钥交换协议,它奠定了现代加密通信的基础。非对称加密相比较对称加密,它是采用的一对密钥来实现加密的,一对密钥包含公钥与私钥,公钥可以公开,私钥我们需要进行保密保管,因为私钥不需要分发。优点:如我们上方所说非对称加密采用一对密钥来加密,可以大大增强数据的完整性和真实性,而且,非对称加密还可以用于数字签名。说了这么多,了解了俩种加密方式,我们来了解一下,非对称加密有哪几种常见的加密方式。 阅读详情

目录

一、加密注意事项

二、openssl 生成密钥对(PEM文件)

三、代码实现

1、读取 PEM 密钥文件

2、加解密

3、生成签名(sign)


因公司业务需要和其他公司做接口对接,对方明确需要使用 RSA + AES 保障数据安全,AES 对称加密用于对请求参数加密,RSA 主要做签名和核心数据的加解密。所以使用本博客记录下要点。

一、加密注意事项

在使用 AES 的时候遇到的,加解密时报错:

java.security.InvalidKeyException: Illegal key size or default parameters

经过度娘的帮助原来是缺少了 OracleJDK 的权限文件,所以需要去官网下载,下载地址:
http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html (JDK8版本的)
下载后将 local_policy.jar 和US_export_policy.jar 两个文件放到 ${JAVA_HOME}/jre/lib/security 目录下即可。

二、openssl 生成密钥对(PEM文件)

  • 生成私钥
openssl genrsa -out rsa_private_key.pem 1024

生成一个 1024 位的私钥,并保存到 rsa_private_key.pem 文件中。这个时候密钥是 pkcs1 格式的,无法被 java 程序使用,需要转换为 pkcs8 格式的

  • 转换私钥为 pkcs8
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_pkcs8.pem

pkcs8 转换的参数详解见博客:openssl pkcs8_艾-小小雨的博客-优快云博客_openssl pkcs8

  • 生成公钥
openssl rsa -in private_pkcs8.pem -pubout -out public_pkcs8.pem

使用 rsa 库利用私钥生成对应的公钥,rsa 生成的公钥就是 pkcs8 格式的,所以无需转换。

三、代码实现

直接使用 hutool 工具包,开箱即用。

<!-- 引入所有模块 -->
<dependency>
  <groupId>cn.hutool</groupId>
  <artifactId>hutool-all</artifactId>
  <version>${hutool.version}</version>
</dependency>

<!-- 或者:只引入加解密模块:提供对称、非对称和摘要算法封装 -->
<dependency>
  <groupId>cn.hutool</groupId>
  <artifactId>hutool-crypto</artifactId>
  <version>${hutool.version}</version>
</dependency>

1、读取 PEM 密钥文件

/**
 * 读取 pem 文件的测试(pkcs8 格式的文件)
 */
@Test
public void readKeyFromPem() throws IOException {
    // 通过 hutool 封装的工具:读取公钥
    String publicKey;
    try (InputStream is = getClass().getClassLoader().getResourceAsStream("public_pkcs8.pem")) {
        byte[] bytes = BCUtil.readKeyBytes(is);
        PublicKey pk = KeyUtil.generateRSAPublicKey(bytes);
        publicKey = Base64Encoder.encode(pk.getEncoded());
    }
	// 读取私钥
    String privateKey;
    try (InputStream is = getClass().getClassLoader().getResourceAsStream("private_pkcs8.pem")) {
        PrivateKey pk = BCUtil.readPrivateKey(is);
        privateKey = Base64Encoder.encode(pk.getEncoded());
    }

	System.out.println(publicKey);
	System.out.println(privateKey);
}

这样就把 PEM 文件读取并转换为代码中可用的公钥和私钥了。

那为什么公钥和私钥的读取 API 会有差异呢?

通过查看源码 BCUtil#readPrivateKey方法关键的地方是:

// KeyUtil 工具类
public static PrivateKey generatePrivateKey(String algorithm, byte[] key) {
    return null == key ? null : generatePrivateKey(algorithm, (KeySpec)(new PKCS8EncodedKeySpec(key)));
}

加载私钥是使用的 PKCS8EncodedKeySpec编码器,而生成的私钥也是 pkcs8 格式,所以能够正常读取。

而 BCUtil#readPublicKey读取公钥的源码如下:

// BCUtils 工具类
public static PublicKey readPublicKey(InputStream pemStream) {
    Certificate certificate = KeyUtil.readX509Certificate(pemStream);
    return null == certificate ? null : certificate.getPublicKey();
}

直接就使用 readX509Certificate编码器,那么读取的就是 X509 格式的公钥文件,但是 openssl 生成的公钥是 pkcs8 格式的,格式不一致会读取不到公钥,所以不能直接使用这个 API,就只能使用上面测试用例的公钥读取方式。

2、加解密

/**
 * 加解密测试:RSA/ECB/PKCS1Padding 算法实现
 */
@Test
public void rsa() throws Exception {
    // 使用上面的测试用例的方式拿到了公钥和私钥了
	String publicKey = ...;
	String privateKey = ...;

    String body = "hello hutool";
	
    // 公钥加密
    String encrypt = SecureUtil.rsa(null, publicKey)
            .encryptBase64(body.getBytes(), KeyType.PublicKey);

    System.out.println("密文 = " + encrypt);

    // 私钥解密
    String content = SecureUtil.rsa(privateKey, null)
            .decryptStr(encrypt, KeyType.PrivateKey);
    System.out.println("解密 = " + content);
	System.out.println("原文 = " + body);
}

RSA 只是非对称加密的一个大类总称,其实现有不同的算法——通过不同的填充规则实现的,加大破解难度。所以实现的算法(填充)如下:

  •  RSA:常规的算法
  • RSA/ECB/PKCS1Padding:使用 pkcs1_padding 算法填充(推荐的)
  • RSA/None/NoPadding:不使用填充
  • EC

通过 SecureUtil.rsa(privateKey, publicKey)创建的 Rsa 对象,默认的就是 RSA/ECB/PKCS1Padding 算法,AsymmetricAlgorithm枚举中定义了这些算法类型,所以要使用其他实现直接使用 public RSA(String rsaAlgorithm, String privateKeyStr, String publicKeyStr)这个构造方法创建即可。

3、生成签名(sign)

最开始我简单的认为就是使用私钥简单的将数据加密,就形成了签名(sign),结果大错特错,这样生成的签名,别人验证不通过,因为行业规定的签名是需要加入摘要算法的,让签名不可逆,也就无法破解签名中的内容。而 hutool 已经实现了签名工具类了,直接使用即可。
首先需要依据提前约定好的规则对数据生成待签名的字符串(一般都是参数key的字典排序 + md5 摘要形成的字符串),然后对字符串生成签名,如下:

/**
 * 签名测试:sha256 摘要签名
 */
@Test
public void signTest() throws IOException {
    // 假设 signMd5 字符串是通过约定好的规则并通过 MD5 摘要后的一个待签名的字符串
    String signMd5 = "5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A";
    // sha256 加密签名
    Sign signObj = SecureUtil.sign(SignAlgorithm.SHA256withRSA, privateKey, publicKey);
    byte[] signBytes = signObj.sign(signMd5.getBytes());

    System.out.println(Base64.encode(signBytes));
}

SignAlgorithm 中定义了常用的 RSA 签名的摘要算法,这样生成出来的签名才是正确的签名。通过查看源码,签名是使用的私钥进行签名,所以验签要用公钥解密,Sign 对象中已经封装了验签方法:Sign#verify 方法就是用于验签的。
在验签之前,场景需要明确:

  1. A 方通过约定的规则生成字符串,并使用 sha256 摘要后通过自己的私钥加密生成了一个 sign(byte数组 + base64)。
  2. B 方只能拿到 A 方的公钥,那么 B 只能使用公钥将 sign 解密出来,拿到一个 sha256 摘要后的数据(byte数组),而这个时候 B 要验签,也只能通过约定好的规则生成一个字符串,再通过 sha256 摘要后得到一个 data(我方生成的 sign,byte数组),进行对比验签。

明确了这个场景后,hutool 工具包的 Sign#verify 方法已经帮我们实现了以下工作:

  1. 使用公钥解密 sign 
  2. 对我们自己生成的数据 data 进行摘要
  3.  对比

所以我们自己只需要通过约定的规则生成出待签名的字符串,并转换为 byte 数组即可——data原数据,并和接收到的 sign 一起调用:sign.verify(data, sign) 即可完成验签。

Java对称与非对称加密解密(AES与RSA) Java对称 & 非对称加密解密(AES与RSA) 阅读详情

相关推荐

Java非对称加密:RSA 数据加密与解密、数字签名与验签

非对称加密(asymmetric cryptography),也称为公开密钥加密(public-key cryptography),是密码学中的一种重要算法。非对称加密使用一对密钥进行加密和解密操作,这两个密钥分别是公开密钥(public key)和私有密钥(private key)。公开密钥可以公开给任何人使用,而私有密钥则必须保密,只有密钥的持有者才能访问。这两个密钥之间存在数学上的联系,但不能从一个推导出另一个。

pan_junbiao的博客 2034

hutool 进行 sha 256 加密

Hutool是一个Java工具包,它提供了许多实用的工具类,包括加密工具。可以使用Hutool的DigestUtil类来进行SHA-256加密。 以下是一个示例代码,演示如何使用Hutool的DigestUtil类进行SHA-256加密: import cn.hutool.crypto.digest.DigestAlgorithm; import cn.hutool.crypto.digest.DigestUtil; public class HutoolSha256Example {

solocao的专栏 7370

Java实现RSA非对称加密工具类

RSA非对称加密通常运用于对字符串进行加密,通过密钥对(公钥、私钥)实现加密。 通过生成的公钥,对字符串加密后,得到一个加密的字符串,将私钥与这个加密后的字符串进行解密,得到原先的字符串。 Java代码: package com.vandet.indwebproject.utils; import org.apache.commons.codec.binary.Base64; import org.bouncycastle.jce.provider.BouncyCastleProvider; im

vandet100的博客 1956

Hutool工具类使用详解

Hutool是一个Java工具类库,由国内的程序员loolly开发,目的是提供一些方便、快捷、实用的工具类和工具方法,使Java开发者能够更加轻松地处理各种任务。Hutool的特点是简单易用、功能全面、代码清晰、文档完备,支持JDK 1.8及以上版本。目前,Hutool已经被广泛使用,并且已经发布了3.x版本。Hutool 3.x版本的特点是升级了依赖库、增加了一些新的功能和优化了性能。

1万+

Java 非对称加密RSA应用实现

RSA算法是一种非对称加密算法,与对称加密算法不同的是,RSA算法有两个不同的密钥,一个是公钥,一个是私钥。RSA公开密钥密码体制是一种使用不同的加密密钥与解密密钥,“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即私有密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。

谁念西风独自凉 2930

Java 加密算法:对称加密和非对称加密总结

RSA 非对称加密, AES 对称加密

u013558123的博客 3470

【非对称加密】详解及Java实现

非对称加密(Asymmetric Cryptography),也称为公钥加密,是一种使用一对密钥(公钥和私钥)进行加密和解密的加密方法。它与对称加密的主要区别在于使用了不同的密钥进行加密和解密操作。非对称加密是现代密码学的基石,解决了密钥分发和数字签名等关键安全问题。Java通过和包提供了完整的非对称加密支持。在实际应用中,通常将对称加密和非对称加密结合使用,发挥各自优势:使用非对称加密安全地交换对称密钥,然后使用对称加密加密实际通信数据。理解非对称加密的原理和正确使用方式,对于构建安全系统至关重要。

weixin_34378978的博客 69

Java与JavaScript结合实现RSA非对称加密全解

Java加密架构(JCA)是Java平台的一部分,提供了加密功能的框架和实现,涵盖了广泛的加密技术和算法。JCA通过提供API来使用各种加密算法,同时它还定义了一种服务提供者接口(SPI),允许开发者扩展Java加密功能。JCA在Java的和包中提供了许多类和接口,用于实现消息摘要、数字签名、证书验证等多种安全服务。Java加密扩展(JCE)是JCA的一个扩展,提供了加密、密钥生成和协商、密钥对管理等加密服务。它对JCA的功能进行了增强,包括支持对称加密、公钥加密、密钥协议等。

weixin_31720909的博客 1134

【RSA】简单说说什么是RSA非对称加密

非对称加密,也称为公钥加密,他有一个公钥和密钥,公的用于加密,而密的用于解密,公钥可以公开给任何人使用,而私钥则只有密钥的持有者可以访问,这种机制确保了只有持有私钥的人才能解密由公钥加密的数据,从而提供了高度的安全性;

一捌柒的博客 1644

Keil C51里用printf打印数据,为啥总出乱码?手把手教你%bd、%hd、%ld的正确用法

本文深入解析Keil C51中printf打印数据出现乱码的根本原因,并提供格式符%bd、%hd、%ld的正确用法指南。通过详细的调试技巧和实战案例,帮助开发者解决串口输出问题,提升单片机开发效率。

weixin_26854829的博客 281

SpringBoot与Flowable整合:构建高效审批工作流的实战指南

本文是一份SpringBoot与Flowable整合构建高效审批工作流的实战指南。通过一个经典的二级审批场景,详细介绍了从项目搭建、BPMN流程设计、核心服务编写到RESTful API构建的完整步骤。文章深入探讨了如何利用Flowable工作流引擎实现审批流程的自动化驱动与灵活管理,并分享了变量管理、监听器、异步执行等进阶技巧与常见避坑指南,帮助开发者快速构建健壮、可维护的企业级审批系统。

qsc9012345的博客 519

Jwt与RSA非对称加密

Jwt与RSA加密1. 无状态登录原理1.1 什么是有状态?1.2 什么是无状态1.3 如何实现无状态1.4 JWT1.4.1 简介1.4.2 数据格式1.4.3 JWT交互流程1.4.4 非对称加密1.5 结合Zuul的鉴权流程1.5.1 没有RSA加密时1.5.2 结合RSA的鉴权 1. 无状态登录原理 在分布式系统当中,传统的登录会失效(原因:各微服务间用的不是同一台tomcat,我们以前登...

xiazhiyou 9946

电流模架构Bandgap设计与仿真

带隙基准作为集成电路中一个重要模块,被广泛应用在低压差线性稳压(LDO)、充电电池保护芯片和通信电路、射频收发器、flash存储器等多种模拟及数模混合集成电路中,并且是片上集成系统(SOC)芯片中不可或缺的部分,为整个芯片提供精确的电压参考点............

qq_50968231的博客 5万+

非对称加密之RSA是怎么加密的?

前几天刚刚说了这个,因为 MD5 也确实用的人不是很多了,就不再继续的一一赘述了,今天就给大家分享的,是非对称加密中的一种,那就是 RSA 加密算法。

LoveSummer 2万+

AUTOSAR 3万字面试题全面解析(持续更新)

ECU抽象层(EAL)是AUTOSAR架构中的一部分,它位于微控制器抽象层(MCAL)之下,但通常与MCAL一起被提及。EAL的目标是提供一个统一的接口来访问和管理ECU(Electronic Control Unit,电子控制单元)的硬件资源,包括处理器、存储器和外围设备。通过这种抽象,EAL使得上层软件能够以一种标准化的方式与ECU硬件交互,而不需要关心具体的硬件实现细节。EAL解决了硬件异构性带来的问题,即不同ECU可能采用不同类型的处理器和硬件配置。

大模型大数据攻城狮的专栏 5609

​​手把手教你学PCIE--ATU 的 Bar 匹配模式与地址匹配模式详解​

摘要: ATU(地址转换单元)提供两种地址匹配模式:Bar匹配模式基于PCI设备的BAR寄存器自动映射虚拟地址(只需配置物理基址),适用于标准PCI设备DMA;地址匹配模式需显式配置虚拟与物理地址范围,适合自定义映射场景。核心区别在于匹配依据(BAR自动推导vs人工定义),Bar模式简化配置,地址模式更灵活。

MHD0815的博客 380

java RSA非对称加密详解

简介RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。1987年首次公布,当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。RSA算法基于一个十分简单的数论事实:将两个大质数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为

罗小辉的专栏 1万+

【HALCON工业视觉应用探索】02. C# + Halcon铸件毛刺机器人打磨引导:点云处理从实验室到工业现场的全流程落地

摘要:铸件毛刺的自动化打磨是机械制造领域的重要难题,其随机性(高度0.1-3mm)和复杂工况导致人工打磨效率低(3分钟/件)、工伤率高。本文基于Halcon 24.11与.NET 6,构建了一套点云处理方案:通过线激光扫描仪获取三维点云,经预处理、毛刺检测、路径规划三大模块,引导机器人完成打磨。虚拟实验测试显示,对高度>1mm的毛刺检出率达100%,定位误差±0.08mm,但工业现场受油污、粉尘影响,性能降至检出率68-75%、处理时间>45秒。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 1128

【RSA】——非对称加密及RSA加密算法

目录 一、非对称加密  1、什么是非对称加密?  2、非对称加密的工作过程  3、非对称加密的优点  4、非对称加密的不足 二、RSA加密算法  1、什么是RSA加密算法  2、RSA的加密原理 3、RSA加密的流程  4、实际开发中使用RSA加密需要注意的地方 一、非对称加密 1、什么是非对称加密? 非对称加密是指,需要用一对儿密钥,即公钥和私钥,来完成加...

我爱吃土豆 7514

【MATLAB】嵌入式ADC/DAC控制工程

摘要:本文针对嵌入式ADC/DAC应用中存在的量化误差、采样噪声、输出漂移等问题,提出基于MATLAB的仿真优化方案。通过构建完整的ADC/DAC仿真模型,实现了采样建模、数字滤波、误差校准和闭环控制仿真。方案采用滑动平均滤波抑制ADC噪声,双校准参数补偿DAC固有误差,并将算法轻量化移植至STM32平台。实测表明,该方案使ADC采样波动从±25mV降至±5mV,DAC输出偏差从42mV降至18mV,显著提升了模拟量交互精度和系统稳定性。整套方案资源占用低,适配各类嵌入式高精度控制场景,具有较高的工程应用价

unber的博客 649

C语言使用开源库libusb进行USB设备操作

https://libusb.info/libusb is a C library that provides generic access to USB devices. It is intended to be used by developers to facilitate the production of applications that communicate with USB hardware. It is portable: Using a single cross-platform AP

m0_60352504的博客 1554

RSA非对称加密(附工具类Util)

RSA非对称加密(附工具类Util)

Javaの甘乃迪的博客 4840

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

深入理解非对称加密:用Java实现RSA加解密

在现代安全通信中,非对称加密广泛应用于数据保护、身份验证、数字签名、SSL/TLS协议等场景。非对称加密算法中最常见的算法是 RSA(Rivest-Shamir-Adleman)算法。

u012372850的专栏 1699

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

JAVA RSA非对称加密工具类

RSATestUtils.java import org.apache.tomcat.util.codec.binary.Base64; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import java.nio.chars..

默默不代表沉默 1710

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

RSA非对称加密简析-java

1 非对称加密算法 1.1 概述   1976年,美国学者Dime和Henman为解决信息公开传送和密钥管理问题,提出一种新的密钥交换协议,允许在不安全的媒体上的通讯双方交换信息,安全地达成一致的密钥,这就是“公开密钥系统”。   与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进...

weixin_33795806的博客 1921

Android之RSA非对称加密

前几天记录了一下:Android之常用的加密算法,大概了解一下各种加密的适用的情况,今天有时间在此总结一下RSA算法。 项目中需要使用非对称加密,其实和Java后台数据交互,只需要对某些关键字段使用此种加密即可,因为加密强度大自然效率低。并且移动端和后台双方实现也都不是很难。 一、简介 RSA算法1978年出现,是第一个既能用于数据加密也能用于数字签名的算法,易于理解和操作。发明者:Ron ...

Zachary的基地 3149
上一篇: java实现排列组合算法
下一篇: Nginx proxy_pass反向代理动态端口
网上搬砖
博客等级 码龄6年 4粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值