加密与安全_AES RSA 密钥对生成及PEM格式的代码实现

2024-05-27 06:12

本文主要是介绍加密与安全_AES RSA 密钥对生成及PEM格式的代码实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • RSA(非对称)和AES(对称)加密算法
    • 一、RSA(Rivest-Shamir-Adleman)
    • 二、AES(Advanced Encryption Standard)
  • RSA加密三种填充模式
    • 一、RSA填充模式
    • 二、常见的RSA填充模式组合
    • 三、选择合适的填充模式
    • 四、总结
  • AES的基本原理、工作模式、填充机制以及密钥和初始化向量(IV)的使用
    • 一、AES简介
    • 二、AES加密解密过程
    • 三、AES常见的工作模式
    • 四、AES填充模式
    • 五、AES密钥和初始化向量管理
  • RSA 生成 Code
    • 一、Java中的RSA加密实现
    • 二、选择合适的密钥长度
    • 三、密钥的管理和存储
      • Code: 将密钥转换为PEM格式
    • 四、总结

在这里插入图片描述


RSA(非对称)和AES(对称)加密算法

在现代信息安全中,加密算法扮演着至关重要的角色。今天我们来聊聊两种常见的加密算法——RSA和AES,用通俗易懂的语言带大家理解它们的核心原理和优缺点。

一、RSA(Rivest-Shamir-Adleman)

核心原理:
RSA是一种非对称加密算法,这意味着它使用一对密钥:公钥和私钥。通俗来说,公钥可以公开,用来加密信息;而私钥需要保密,用来解密信息。它的安全性主要依赖于一个数学难题:大整数的质因数分解。具体步骤如下:

  1. 选择质数:选择两个大质数p和q。
  2. 计算乘积:计算p和q的乘积n = p * q,这就是公钥的一部分。
  3. 计算欧拉函数:计算欧拉函数φ(n) = (p-1)*(q-1)。
  4. 选择公钥指数:选择一个小于φ(n)的整数e,且e与φ(n)互质,这就是公钥的另一部分。
  5. 计算私钥指数:计算e对于φ(n)的模反元素d,这就是私钥。

优点:

  • 安全性高:由于大整数的质因数分解非常困难,破解RSA几乎不可能。
  • 公钥加密:公钥可以公开分享,方便信息的安全传输。

缺点:

  • 速度慢:加密和解密过程计算复杂,速度较慢。
  • 密钥长度大:需要较长的密钥(通常为2048位或以上)来保证安全性,存储和处理成本高。

二、AES(Advanced Encryption Standard)

核心原理:
AES是一种对称加密算法,这意味着它使用同一个密钥进行加密和解密。它基于一种叫做“分组密码”的方法,把数据分成固定大小的块(通常是128位),然后通过多个轮次的处理来加密数据。每轮处理包括以下步骤:

  1. 替代(Substitution):使用预先定义的S盒对数据进行替换。
  2. 换位(Permutation):重新排列数据的顺序。
  3. 混淆(Mixing):对数据进行复杂的数学运算混合。
  4. 轮密钥加(Add Round Key):与轮密钥进行异或运算。

优点:

  • 速度快:由于AES算法的设计简单且高效,处理速度快,适合大数据量的加密。
  • 安全性高:AES算法在多年的使用中,未被成功破解,具有很高的安全性。

缺点:

  • 密钥管理复杂:对称加密要求通信双方事先共享同一个密钥,密钥的分发和管理较为复杂。
  • 密钥泄露风险:一旦密钥泄露,所有加密的数据都会暴露,因此密钥保护非常重要。

RSA和AES是现代密码学中两种重要的加密算法,各有优缺点。RSA依赖于复杂的数学难题,安全性高但速度较慢;AES则以其高效的加密速度和广泛应用而著称,但在密钥管理上存在挑战。


RSA加密三种填充模式

RSA加密算法在实际应用中常常使用填充模式来确保数据的安全性和算法的有效性。

填充模式是为了使加密数据和公钥长度一致,并增加加密的安全性。

接下来我们看下主要的RSA填充模式:ENCRYPTION_OAEPENCRYPTION_PKCS1ENCRYPTION_NONE,以及常见的填充模式组合。

一、RSA填充模式

1. ENCRYPTION_OAEP(Optimal Asymmetric Encryption Padding)

  • 简介:OAEP是目前最安全的RSA填充模式,广泛推荐用于现代加密应用中。
  • 原理:OAEP在加密数据前,先通过一个哈希函数和一个掩码生成函数(MGF)对数据进行填充,确保每次加密的结果都不同,即使相同的数据和密钥也不会产生相同的密文。
  • 优点:高安全性,防止多种已知攻击(如选择密文攻击)。
  • 使用场景:需要高度安全性的数据加密和解密操作。

2. ENCRYPTION_PKCS1(PKCS #1 v1.5 Padding)

  • 简介:PKCS1是RSA加密最常用的填充模式之一,因其随机填充的特性,确保相同数据每次加密结果不同。
  • 原理:PKCS1填充在数据前面添加一个随机填充字符串,并确保数据长度和密钥长度一致。
  • 优点:较为简单,已经广泛使用和支持。
  • 缺点:相对于OAEP,安全性略低,可能受到一定类型的攻击(如选择密文攻击)。
  • 使用场景:一般数据加密,广泛应用于SSL/TLS协议中。

3. ENCRYPTION_NONE(No Padding)

  • 简介:无填充模式,直接对数据进行加密。
  • 原理:数据长度必须与密钥长度相同,不进行任何额外的填充处理。
  • 优点:实现简单。
  • 缺点:安全性较低,易受各种攻击,不推荐使用。
  • 使用场景:通常仅在特定条件下或内部使用。

二、常见的RSA填充模式组合

1. RSA/None/PKCS1Padding

  • 简介:该模式表示没有指定具体的块加密模式(None),使用PKCS1填充。
  • 特点:确保相同数据每次加密结果不同,适用于许多常见的加密场景。

2. RSA/ECB/PKCS1Padding

  • 简介:该模式表示使用电子密码本(ECB)模式进行加密,并使用PKCS1填充。
  • 特点:在每个块中独立加密,但ECB模式本身不推荐用于大数据量的加密,因为相同的明文块会被加密成相同的密文块,这可能导致模式泄露问题。
  • 适用场景:一般数据加密,广泛应用于加密协议中。

三、选择合适的填充模式

选择合适的填充模式需要根据具体应用场景来考虑:

  1. 高安全性需求:推荐使用ENCRYPTION_OAEP填充模式,尤其是在敏感数据的加密和解密中。
  2. 广泛兼容性:ENCRYPTION_PKCS1是一个较好的选择,已经被广泛支持和使用,适用于大多数应用场景。
  3. 实验性或内部使用:ENCRYPTION_NONE模式仅在特定情况下使用,需确保其他安全措施到位。

四、总结

RSA加密算法的填充模式是确保数据安全性和算法有效性的关键。ENCRYPTION_OAEP、ENCRYPTION_PKCS1和ENCRYPTION_NONE各有优缺点和适用场景。在实际应用中,根据具体需求选择合适的填充模式,能够有效提升加密的安全性和性能。


AES的基本原理、工作模式、填充机制以及密钥和初始化向量(IV)的使用

AES(Advanced Encryption Standard)是一种广泛使用的对称加密算法,旨在替代原先的DES和3DES。AES凭借其高效的加密速度和强大的安全性,成为现代数据加密的首选。

接下来我们来看下AES的基本原理、工作模式、填充机制以及密钥和初始化向量(IV)的使用。

一、AES简介

主要特点:

  • 对称加密:同一个密钥用于加密和解密。
  • 块加密:以固定大小的块(128位)对数据进行加密。
  • 高效性:比公钥加密算法快很多,适用于需要高性能的数据加密场景。

主要缺点:

  • 密钥管理:需要加密端和解密端都使用相同的密钥,密钥分发和管理较为复杂。

二、AES加密解密过程

AES加密需要:

  • 明文:需要加密的数据。
  • 密钥(Key):用于加密和解密的密钥,长度可以是128位、192位或256位。
  • 偏移量(IV):初始化向量,用于将加密随机化,提高安全性。
  • 密码模式:算法/模式/填充,如AES/CBC/PKCS5Padding。

AES解密需要:

  • 密文:已加密的数据。
  • 密钥(Key):与加密时使用的密钥相同。
  • 偏移量(IV):与加密时使用的初始化向量相同。
  • 密码模式:算法/模式/填充,如AES/CBC/PKCS5Padding。

三、AES常见的工作模式

1. 电码本模式(ECB)

  • 特点:每个数据块独立加密,相同的明文块会被加密成相同的密文块。
  • 优点:实现简单,不需要初始化向量。
  • 缺点:不安全,容易受到模式泄露攻击。
  • 使用场景:不推荐在安全需求高的场景下使用。

2. 密码分组链接模式(CBC)

  • 特点:每个明文块与前一个密文块进行异或运算后再加密,第一个块需要初始化向量(IV)。
  • 优点:安全性高,每个块的加密结果都不同。
  • 使用场景:广泛用于文件加密和数据传输加密。

3. 计算器模式(CTR)

  • 特点:将一个计数器的输出与明文块进行异或运算,实现加密。
  • 优点:可并行处理,提高加密速度。
  • 使用场景:适用于流式数据加密和高性能需求的场景。

4. 密码反馈模式(CFB)

  • 特点:前一个密文块作为下一块的输入,结合初始化向量(IV)提高安全性。
  • 优点:适用于需要逐字节或逐位加密的场景。
  • 使用场景:实时数据加密,如网络数据流。

5. 输出反馈模式(OFB)

  • 特点:将初始化向量与密钥结合,通过反馈机制生成加密序列。
  • 优点:加密过程独立于明文块的内容。
  • 使用场景:适用于逐位加密和需要抗噪声的场景。

四、AES填充模式

填充模式的必要性:
由于AES是一种块加密算法,处理的数据块必须是固定长度(128位),因此需要填充模式来确保数据长度符合要求。

常见填充模式:

  • PKCS7:在数据末尾添加一系列字节,每个字节的值表示填充的字节数,广泛使用,兼容性好。
  • None:不进行填充,要求输入数据的长度必须是块长度的整数倍。

五、AES密钥和初始化向量管理

密钥(Key):

  • AES标准规定的密钥长度为128位、192位和256位,分别对应16字节、24字节和32字节。
  • 密钥不能公开传输,需要安全地管理和保护。

初始化向量(IV):

  • IV用于将加密随机化,确保相同的明文被多次加密产生不同的密文。
  • IV可以公开,但不能重复使用。推荐每次加密时生成一个新的16字节随机值。
  • 在加密端将IV和密文一起发送给解密端,确保解密端能够正确还原数据。

RSA 生成 Code

RSA加密算法在Java中有多种实现方式,其中默认的实现方式是RSA/None/PKCS1Padding。在实际应用中,为了确保安全性和兼容性,需要注意密钥长度、密钥格式以及密钥管理。

一、Java中的RSA加密实现

默认实现:RSA/None/PKCS1Padding

  • RSA:表示使用RSA算法进行加密。
  • None:没有指定具体的块加密模式。
  • PKCS1Padding:使用PKCS#1 v1.5填充模式,这是常见的RSA填充方式。

为什么选择PKCS1Padding?

PKCS1Padding是一种较为常用且广泛支持的填充方式,它通过添加随机填充数据,确保相同的数据每次加密结果不同,从而提高安全性。

二、选择合适的密钥长度

推荐使用2048位或更长的密钥

  • 1024位密钥:在现代计算能力下已经不再安全,容易受到攻击。
  • 2048位或更长的密钥:提供更高的安全性,推荐使用2048位或4096位的密钥,以应对未来更强的攻击手段。

创建RSA密钥对

 package com.artisan.jasypt.rsa;import java.io.UnsupportedEncodingException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Base64;/*** @author 小工匠* @version 1.0* @mark: show me the code , change the world*/
public class RsaTest {/*** 主程序入口,用于演示如何生成和打印RSA密钥对的公钥和私钥。** @param args 命令行参数(未使用)* @throws UnsupportedEncodingException 如果编码不被支持*/public static void main(String[] args) throws UnsupportedEncodingException {// 生成2048位的RSA密钥对KeyPair keyPair = getKeyPair(2048);// 获取公钥byte[] publicKey = getPublicKey(keyPair);// 获取私钥byte[] privateKey = getPrivateKey(keyPair);// 打印编码后的公钥和私钥System.out.println("Private Key: " + Base64.getEncoder().encodeToString(publicKey));System.out.println("Public Key: " + Base64.getEncoder().encodeToString(privateKey));}/*** 生成RSA算法的密钥对* @param keyLength 密钥长度,用于初始化密钥生成器* @return 生成的密钥对,包含公钥和私钥*/public static KeyPair getKeyPair(int keyLength) {try {// 实例化密钥对生成器,并指定算法为RSAKeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");// 初始化密钥对生成器,设置密钥长度keyPairGenerator.initialize(keyLength);// 生成密钥对return keyPairGenerator.generateKeyPair();} catch (NoSuchAlgorithmException e) {// 当指定的加密算法不可用时,抛出运行时异常throw new RuntimeException("生成密钥对时遇到异常" +  e.getMessage());}}/*** 获取公钥** @param keyPair 包含公钥和私钥的密钥对* @return 公钥的字节数组形式*/public static byte[] getPublicKey(KeyPair keyPair) {// 将密钥对中的公钥转换为RSAPublicKey类型RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();// 获取并返回公钥的编码形式return rsaPublicKey.getEncoded();}/*** 获取私钥** @param keyPair 包含公钥和私钥的密钥对* @return 返回私钥的字节数组形式*/public static byte[] getPrivateKey(KeyPair keyPair) {// 将keyPair中的私钥转换为RSAPrivateKey类型RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();// 返回私钥的编码形式return rsaPrivateKey.getEncoded();}}
 package com.artisan.jasypt.rsa;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;/*** @author 小工匠* @version 1.0* @mark: show me the code , change the world*/
public class RSAKeyPairGenerator {/*** 主函数用于生成RSA算法的密钥对,并打印出其Base64编码的字符串形式。** @param args 命令行参数(未使用)* @throws NoSuchAlgorithmException 如果指定的加密算法不可用,则抛出此异常。*/public static void main(String[] args) throws NoSuchAlgorithmException {// 创建RSA算法的密钥对生成器KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");// 初始化密钥对生成器,设置密钥长度为2048位keyPairGen.initialize(2048);// 生成密钥对KeyPair pair = keyPairGen.generateKeyPair();// 从密钥对中提取私钥和公钥PrivateKey privateKey = pair.getPrivate();PublicKey publicKey = pair.getPublic();// 打印出私钥和公钥的Base64编码System.out.println("Private Key: " + Base64.getEncoder().encodeToString(privateKey.getEncoded()));System.out.println("Public Key: " + Base64.getEncoder().encodeToString(publicKey.getEncoded()));}}

三、密钥的管理和存储

密钥生成与存储的流程

  • 服务器创建密钥对:服务器负责生成RSA密钥对,确保私钥的安全存储。
  • 公钥下发至客户端:将公钥分发给需要加密数据的客户端。
  • 私钥保存在服务器:私钥必须保密,通常存储在服务器上,确保其不被泄露。

密钥格式:DER和PEM

  • DER(Distinguished Encoding Rules):二进制格式,主要用于机器处理,不便于阅读。
  • PEM(Privacy-Enhanced Mail):将DER格式通过Base64编码转换为字符格式,更易于阅读和传输。

PEM格式的密钥示例

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr8p1oxcLljRG/Qffkh6N
...
-----END PUBLIC KEY----------BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCr8p1oxcLljRG/
...
-----END PRIVATE KEY-----

Code: 将密钥转换为PEM格式

 package com.artisan.jasypt.rsa;import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;
/*** @author 小工匠* @version 1.0* @mark: show me the code , change the world*/
public class KeyToPEM {/*** 主函数:生成RSA密钥对,并将其转换为PEM格式输出。** @param args 命令行参数(未使用)* @throws Exception 如果密钥生成或转换过程中发生错误*/public static void main(String[] args) throws Exception {// 生成RSA密钥对,使用2048位长度KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");keyGen.initialize(2048);KeyPair keyPair = keyGen.generateKeyPair();// 提取公钥和私钥PublicKey publicKey = keyPair.getPublic();PrivateKey privateKey = keyPair.getPrivate();// 将公钥和私钥转换为PEM格式String publicKeyPEM = convertToPEMFormat(publicKey.getEncoded(), "PUBLIC KEY");String privateKeyPEM = convertToPEMFormat(privateKey.getEncoded(), "PRIVATE KEY");// 输出转换后的PEM格式公钥和私钥System.out.println(publicKeyPEM);System.out.println(privateKeyPEM);}/*** 将密钥字节数组转换为PEM格式的字符串。* PEM(Privacy Enhanced Mail)格式是一种常见的密钥存储格式,以 base64 编码的密钥数据为主要内容,并以“-----BEGIN”和“-----END”为标记。** @param key 密钥的字节数组。* @param keyType 密钥的类型(如RSA PRIVATE KEY等)。* @return 转换后的PEM格式密钥字符串。*/public static String convertToPEMFormat(byte[] key, String keyType) {// 将密钥字节数组转换为Base64编码的字符串String base64EncodedKey = Base64.getEncoder().encodeToString(key);StringBuilder pemKey = new StringBuilder();// 添加PEM格式的起始标记pemKey.append("-----BEGIN ").append(keyType).append("-----\n");// 将Base64编码的密钥拆分为64字符一组,并添加换行符for (int i = 0; i < base64EncodedKey.length(); i += 64) {pemKey.append(base64EncodedKey, i, Math.min(i + 64, base64EncodedKey.length())).append("\n");}// 添加PEM格式的结束标记pemKey.append("-----END ").append(keyType).append("-----");return pemKey.toString();}
}

四、总结

RSA加密在Java中的默认实现是RSA/None/PKCS1Padding,推荐使用2048位或更长的密钥以确保安全。密钥管理是保证加密系统安全的重要环节,私钥应保存在服务器上,公钥分发给客户端。PEM格式的密钥更易于阅读和传输,通常用于存储和交换密钥。

在这里插入图片描述

这篇关于加密与安全_AES RSA 密钥对生成及PEM格式的代码实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1006679

相关文章

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

hevc和H.264格式的区别

HEVC(High Efficiency Video Coding)和H.264(也称为Advanced Video Coding,AVC)都是视频压缩标准,但它们之间存在一些显著的区别,主要集中在压缩效率、资源需求和兼容性方面。 压缩效率 HEVC,也被称为H.265,提供了比H.264更高的压缩效率。这意味着在相同的视频质量下,HEVC能够以大约一半的比特率进行编码,从而减少存储空间需求和

uniapp接入微信小程序原生代码配置方案(优化版)

uniapp项目需要把微信小程序原生语法的功能代码嵌套过来,无需把原生代码转换为uniapp,可以配置拷贝的方式集成过来 1、拷贝代码包到src目录 2、vue.config.js中配置原生代码包直接拷贝到编译目录中 3、pages.json中配置分包目录,原生入口组件的路径 4、manifest.json中配置分包,使用原生组件 5、需要把原生代码包里的页面修改成组件的方

公共筛选组件(二次封装antd)支持代码提示

如果项目是基于antd组件库为基础搭建,可使用此公共筛选组件 使用到的库 npm i antdnpm i lodash-esnpm i @types/lodash-es -D /components/CommonSearch index.tsx import React from 'react';import { Button, Card, Form } from 'antd'

17.用300行代码手写初体验Spring V1.0版本

1.1.课程目标 1、了解看源码最有效的方式,先猜测后验证,不要一开始就去调试代码。 2、浓缩就是精华,用 300行最简洁的代码 提炼Spring的基本设计思想。 3、掌握Spring框架的基本脉络。 1.2.内容定位 1、 具有1年以上的SpringMVC使用经验。 2、 希望深入了解Spring源码的人群,对 Spring有一个整体的宏观感受。 3、 全程手写实现SpringM

通过SSH隧道实现通过远程服务器上外网

搭建隧道 autossh -M 0 -f -D 1080 -C -N user1@remotehost##验证隧道是否生效,查看1080端口是否启动netstat -tuln | grep 1080## 测试ssh 隧道是否生效curl -x socks5h://127.0.0.1:1080 -I http://www.github.com 将autossh 设置为服务,隧道开机启动

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测 目录 时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测基本介绍程序设计参考资料 基本介绍 MATLAB实现LSTM时间序列未来多步预测-递归预测。LSTM是一种含有LSTM区块(blocks)或其他的一种类神经网络,文献或其他资料中LSTM区块可能被描述成智能网络单元,因为

vue项目集成CanvasEditor实现Word在线编辑器

CanvasEditor实现Word在线编辑器 官网文档:https://hufe.club/canvas-editor-docs/guide/schema.html 源码地址:https://github.com/Hufe921/canvas-editor 前提声明: 由于CanvasEditor目前不支持vue、react 等框架开箱即用版,所以需要我们去Git下载源码,拿到其中两个主

代码随想录算法训练营:12/60

非科班学习算法day12 | LeetCode150:逆波兰表达式 ,Leetcode239: 滑动窗口最大值  目录 介绍 一、基础概念补充: 1.c++字符串转为数字 1. std::stoi, std::stol, std::stoll, std::stoul, std::stoull(最常用) 2. std::stringstream 3. std::atoi, std

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现