加密与安全_探索对称加密算法

文章目录

  • 概述
  • 常用的对称加密算法
  • AES
    • ECB模式
    • CBC模式 (推荐)
    • ECB VS CBC
  • 附:AES工具类
  • 总结

在这里插入图片描述


概述

对称加密算法是一种加密技术,使用相同的密钥来进行加密和解密数据。在这种算法中,发送方使用密钥将明文(未加密的数据)转换为密文(加密的数据),而接收方使用相同的密钥将密文还原为明文。

对称加密算法的安全性依赖于密钥的保密性,因为任何持有相同密钥的人都能够解密数据。

常见的对称加密算法包括AES(高级加密标准)和DES(数据加密标准)。虽然对称加密算法在性能上通常比非对称加密算法更高效,但在密钥管理和分发方面存在挑战。

通俗来讲,可以这么理解: 对称加密算法就像是一把钥匙可以打开一个锁。在这里,你有一个钥匙(密钥),用它来锁住(加密)你的信息,然后你可以用同样的钥匙(密钥)来解锁(解密)它。这意味着发送方和接收方都使用相同的密钥来加密和解密信息。


常用的对称加密算法

常用的对称加密算法包括:

  1. AES(Advanced Encryption Standard):这是目前最常用的对称加密算法之一。它使用128、192或256位密钥来加密数据,并已被广泛采用于许多安全应用中。

  2. DES(Data Encryption Standard):虽然已被AES所取代,但仍然在一些遗留系统中使用。DES使用56位密钥对数据进行加密。

  3. 3DES(Triple Data Encryption Standard):3DES是DES的改进版本,它对数据应用三次DES算法,提高了安全性。但由于计算成本高昂,现在已经不太常用。

  4. Blowfish:这是一个可扩展的对称加密算法,可以使用变长密钥,从32位到448位。它曾经很流行,但由于一些安全性方面的考虑,现在使用较少。

  5. RC4(Rivest Cipher 4):尽管曾被广泛使用,但由于存在一些严重的安全漏洞,现在已经不建议使用。


从程序的角度看,所谓加密,就是这样一个函数,它接收密码和明文,然后输出密文:

secret = encrypt(key, message);

而解密则相反,它接收密码和密文,然后输出明文:

plain = decrypt(key, secret);  

从程序的角度看,所谓加密,就是这样一个函数,它接收密码和明文,然后输出密文:

secret = encrypt(key, message);

而解密则相反,它接收密码和密文,然后输出明文:

plain = decrypt(key, secret);  

加密和解密确实可以被视为类似上面的函数,但实际上,它们可能会更为复杂一些,尤其是在实现对称加密算法时。

在使用对称加密算法时,这两个函数通常被称为加密函数和解密函数。例如,在使用AES算法时,加密函数会接收密钥(key)和明文(message),然后输出密文(ciphertext)。而解密函数则接收密钥(key)和密文(ciphertext),然后输出明文(message)

算法密钥长度工作模式填充模式
AES128/192/256ECB/CBC/PCBC/CTR/…NoPadding/PKCS5Padding/PKCS7Padding/…
DES56/64ECB/CBC/PCBC/CTR/…NoPadding/PKCS5Padding/…

密钥长度直接决定加密强度,而工作模式和填充模式可以看成是对称加密算法的参数和格式选择。


这些对称加密算法在不同的场景中都有各自的优缺点,选择合适的算法取决于安全性需求、性能和应用环境。AES通常被认为是最安全和高效的对称加密算法之一,因此在许多情况下被首选使用


AES

AES算法是目前应用最广泛的加密算法。

ECB模式

先用ECB模式加密并解密. 代码如下

package com.artisan.securityalgjava.aes;import java.security.*;
import java.util.Base64;import javax.crypto.*;
import javax.crypto.spec.*;/*** @author 小工匠* @version 1.0* @mark: show me the code , change the world*/
public class AesECBExample {public static void main(String[] args) throws Exception {// 原文:String message = "Hello, Artisan!";System.out.println("Message: " + message);// 128位密钥 = 16 bytes Key:byte[] key = "1234567890abcdef".getBytes("UTF-8");// 加密:byte[] data = message.getBytes("UTF-8");byte[] encrypted = encrypt(key, data);System.out.println("Encrypted: " + Base64.getEncoder().encodeToString(encrypted));// 解密:byte[] decrypted = decrypt(key, encrypted);System.out.println("Decrypted: " + new String(decrypted, "UTF-8"));}// 加密方法public static byte[] encrypt(byte[] key, byte[] input) throws GeneralSecurityException {// 创建加密对象Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");// 创建密钥规范SecretKey keySpec = new SecretKeySpec(key, "AES");// 初始化加密对象cipher.init(Cipher.ENCRYPT_MODE, keySpec);// 执行加密操作return cipher.doFinal(input);}// 解密方法public static byte[] decrypt(byte[] key, byte[] input) throws GeneralSecurityException {// 创建解密对象Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");// 创建密钥规范SecretKey keySpec = new SecretKeySpec(key, "AES");// 初始化解密对象cipher.init(Cipher.DECRYPT_MODE, keySpec);// 执行解密操作return cipher.doFinal(input);}
}

ECB模式是最简单的AES加密模式,它只需要一个固定长度的密钥,固定的明文会生成固定的密文,这种一对一的加密方式会导致安全性降低

CBC模式 (推荐)

package com.artisan.securityalgjava.aes;import java.security.*;
import java.util.Base64;import javax.crypto.*;
import javax.crypto.spec.*;/*** @author 小工匠* @version 1.0* @mark: show me the code , change the world* @desc: AES CBC模式加解密示例*/
public class AesCBCExample {public static void main(String[] args) throws Exception {// 原文:String message = "Hello, Artisan!";System.out.println("Message: " + message);// 256位密钥 = 32 bytes Key:byte[] key = "1234567890abcdef1234567890abcdef".getBytes("UTF-8");// 加密:byte[] data = message.getBytes("UTF-8");byte[] encrypted = encrypt(key, data);System.out.println("Encrypted: " + Base64.getEncoder().encodeToString(encrypted));// 解密:byte[] decrypted = decrypt(key, encrypted);System.out.println("Decrypted: " + new String(decrypted, "UTF-8"));}/*** 加密* @param key* @param input* @return* @throws GeneralSecurityException*/public static byte[] encrypt(byte[] key, byte[] input) throws GeneralSecurityException {// 创建AES加密器Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");// 创建密钥规范SecretKeySpec keySpec = new SecretKeySpec(key, "AES");// CBC模式需要生成一个16 bytes的初始化向量SecureRandom sr = SecureRandom.getInstanceStrong();byte[] iv = sr.generateSeed(16);IvParameterSpec ivps = new IvParameterSpec(iv);// 初始化加密器cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivps);// 执行加密操作byte[] data = cipher.doFinal(input);// IV不需要保密,把IV和密文一起返回return join(iv, data);}/*** 解密* @param key* @param input* @return* @throws GeneralSecurityException*/public static byte[] decrypt(byte[] key, byte[] input) throws GeneralSecurityException {// 把input分割成IV和密文byte[] iv = new byte[16];byte[] data = new byte[input.length - 16];System.arraycopy(input, 0, iv, 0, 16);System.arraycopy(input, 16, data, 0, data.length);// 创建AES解密器Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");// 创建密钥规范SecretKeySpec keySpec = new SecretKeySpec(key, "AES");IvParameterSpec ivps = new IvParameterSpec(iv);// 初始化解密器cipher.init(Cipher.DECRYPT_MODE, keySpec, ivps);// 执行解密操作return cipher.doFinal(data);}/*** 拼接两个字节数组* @param bs1* @param bs2* @return*/public static byte[] join(byte[] bs1, byte[] bs2) {byte[] r = new byte[bs1.length + bs2.length];System.arraycopy(bs1, 0, r, 0, bs1.length);System.arraycopy(bs2, 0, r, bs1.length, bs2.length);return r;}}

CBC模式下,需要一个随机生成的16字节IV参数,必须使用SecureRandom生成。因为多了一个IvParameterSpec实例,因此,初始化方法需要调用Cipher的一个重载方法并传入IvParameterSpec

观察输出,可以发现每次生成的IV不同,密文也不同, 如下图所示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码实现了AES CBC模式的加密和解密功能。在加密过程中,生成了一个16字节的初始化向量(IV),在解密时使用了这个IV来确保安全性。

因此,CBC模式,它需要一个随机数作为IV参数,这样对于同一份明文,每次生成的密文都不同 .


ECB VS CBC

AES有几种不同的模式,其中最常见的两种是ECB(Electronic Codebook)模式和CBC(Cipher Block Chaining)模式。

  1. ECB模式(电子密码本模式)
  • 特点
    • 将明文分成块,每个块使用相同的密钥进行加密。
    • 相同的明文块在加密后会得到相同的密文块。
    • 每个块的加密是独立的,不受其他块的影响。
  • 优点
    • 简单,容易并行化处理。
    • 适用于对称加密需求较简单的场景。
  • 缺点
    • 容易受到重放攻击的影响,因为相同的明文块会产生相同的密文块,没有隐藏明文块之间的关系。
    • 不适合加密大量数据或需要保护隐私的数据,因为无法隐藏明文块之间的模式。
  1. CBC模式(密码块链接模式)
  • 特点
    • 在加密前,会对明文块进行异或运算,并与前一个密文块进行混合,然后再加密。
    • 需要一个初始化向量(IV)来增加随机性,防止重放攻击。
    • 密文块的加密依赖于前一个密文块,因此密文块之间存在依赖关系。
  • 优点
    • 对于相同的明文块,使用不同的IV会产生不同的密文块,增加了安全性。
    • 可以加密大量数据,并且可以隐藏明文块之间的模式。
  • 缺点
    • 加密速度较ECB模式慢,因为需要依赖前一个密文块。
    • 不太容易并行化处理,因为每个块的加密都依赖于前一个块的加密结果。

综上所述,ECB模式简单快速,适合简单的加密需求,但安全性较差,不适合加密大量数据或需要保护隐私的数据。而CBC模式相对更安全,能够隐藏明文块之间的模式,适合加密大量数据或需要保护隐私的数据,但加密速度较慢


附:AES工具类

package com.artisan.securityalgjava.aes;import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.security.spec.KeySpec;
import java.util.Arrays;
import java.util.Base64;/*** @author 小工匠* @version 1.0* @mark: show me the code , change the world* @desc: AES加密解密工具类, 提供了AES加密解密的功能,使用了CBC模式和PBKDF2算法生成密钥*/
public class AESCipher {/*** 密钥生成算法*/private static final String SECRET_KEY_ALGORITHM = "PBKDF2WithHmacSHA256";/*** 加密算法*/private static final String ENCRYPTION_ALGORITHM = "AES/CBC/PKCS5Padding";/*** 密钥长度*/private static final int KEY_SIZE = 256;/*** 迭代次数*/private static final int ITERATION_COUNT = 65536;/*** 初始化向量长度*/private static final int IV_SIZE = 16;/*** 生成密钥** @param password* @param salt* @return* @throws Exception*/private static SecretKeySpec generateKey(String password, byte[] salt) throws Exception {SecretKeyFactory factory = SecretKeyFactory.getInstance(SECRET_KEY_ALGORITHM);KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, ITERATION_COUNT, KEY_SIZE);SecretKey tmp = factory.generateSecret(spec);return new SecretKeySpec(tmp.getEncoded(), "AES");}/*** 加密** @param plaintext* @param password* @return* @throws Exception*/public static String encrypt(String plaintext, String password) throws Exception {// 生成盐byte[] salt = new byte[16];// 生成初始化向量byte[] iv = new byte[IV_SIZE];byte[] encryptedBytes;// 生成盐和初始化向量SecureRandom random = new SecureRandom();random.nextBytes(salt);random.nextBytes(iv);// 生成密钥SecretKeySpec keySpec = generateKey(password, salt);Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(iv));// 执行加密操作encryptedBytes = cipher.doFinal(plaintext.getBytes());// 将盐、初始化向量和密文拼接并返回Base64编码字符串byte[] combined = new byte[salt.length + iv.length + encryptedBytes.length];System.arraycopy(salt, 0, combined, 0, salt.length);System.arraycopy(iv, 0, combined, salt.length, iv.length);System.arraycopy(encryptedBytes, 0, combined, salt.length + iv.length, encryptedBytes.length);return Base64.getEncoder().encodeToString(combined);}/*** 解密** @param encryptedText* @param password* @return* @throws Exception*/public static String decrypt(String encryptedText, String password) throws Exception {// 解析Base64编码字符串并分离盐、初始化向量和密文byte[] combined = Base64.getDecoder().decode(encryptedText);byte[] salt = Arrays.copyOfRange(combined, 0, 16);byte[] iv = Arrays.copyOfRange(combined, 16, 32);byte[] encryptedBytes = Arrays.copyOfRange(combined, 32, combined.length);// 生成密钥SecretKeySpec keySpec = generateKey(password, salt);Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv));// 执行解密操作并返回明文字符串byte[] decryptedBytes = cipher.doFinal(encryptedBytes);return new String(decryptedBytes);}/*** 测试方法** @param args* @throws Exception*/public static void main(String[] args) throws Exception {// 测试加密解密功能String encrypted = encrypt("组热么共和国的啥范德萨", "dddd");System.out.println("Encrypted: " + encrypted);String decrypted = decrypt(encrypted, "dddd");System.out.println("Decrypted: " + decrypted);}
}

总结

对称加密算法使用同一个密钥进行加密和解密,适用于需要高效加解密的场景。常见的对称加密算法包括DES、AES和3DES等。

对称加密算法使用同一个密钥进行加密和解密,常用的算法包括DES、AES和3DES等。

  • DES(Data Encryption Standard):DES是一种较早的对称加密算法,使用56位密钥进行加密和解密。由于密钥长度较短,DES已经不再被推荐使用,因为它容易受到穷举攻击。

  • AES(Advanced Encryption Standard):AES是目前广泛使用的对称加密算法之一。它使用128位、192位或256位密钥进行加密和解密。AES算法的安全性和性能较高,因此被广泛应用于各种安全领域。

  • 3DES(Triple Data Encryption Standard):3DES是对DES算法的改进,通过对数据应用三次DES算法来提高安全性。3DES使用的密钥长度为56位,因此它的安全性较DES提高了很多。但由于AES的出现和3DES的计算复杂性,3DES的使用逐渐减少。

密钥长度由算法设计决定。对于AES算法,它支持的密钥长度为128位、192位和256位。一般来说,密钥长度越长,加密的安全性越高,但同时也带来了更高的计算成本。

在使用对称加密算法时,需要指定以下参数:

  • 算法名称:即使用的加密算法,例如DES、AES和3DES等。
  • 工作模式:指定了加密算法在加密大块数据时的工作模式,常见的工作模式包括ECB、CBC、CFB、OFB等。
  • 填充模式:指定了在加密数据块大小不足时如何填充数据,常见的填充模式包括PKCS5Padding、NoPadding等。

选择合适的算法名称、工作模式和填充模式,可以根据具体的安全需求和性能要求进行调整。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/713612.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

14:00面试,14:07就出来了,问的问题过于变态了。。。

我从一家小公司转投到另一家公司,期待着新的工作环境和机会。然而,新公司的加班文化让我有些始料未及。虽然薪资相对较高,但长时间的工作和缺乏休息使我身心俱疲。 就在我逐渐适应这种高强度的工作节奏时,公司突然宣布了一则令人…

kafka学习笔记三

目录 第二篇 外部系统集成 第三篇 生产调优手册 第1章 kafka硬件配置选择 第2章 生产者调优 2.1 生产者核心参数配置 2.2 生产者如何提高吞吐量 2.3 数据可靠性 2.4 数据去重 2.5 数据有序 2.6 数据乱序 第3章 Kafka Broker调优 3.1 Broker核心参数配置 3.2 其他 …

禅道:提bug、管理case 7.0

一、禅道的介绍 (1)定义禅道是一个项目管理工具,也是一个bug管理工具,还是一个用例管理工具。 (2)作用:为了解决众多企业在管理中出现混乱,无序的现象,开发出来 &…

ppt中调整某条表格框线的格式

1、先设置好边框线的属性: 2、选择要调整的边框线所在的单元格(第二列的右边框加粗,体现分栏的效果) 3、设计--边框--中选择要调整的边框线位置(假设要调整右框线)

libvirt命名空间xmlns:qemu的使用

示例xml <domain type{domain_type} xmlns:qemuhttp://libvirt.org/schemas/domain/qemu/1.0><qemu:commandline><qemu:commandline><qemu:arg value-newarg/><qemu:env nameQEMU_ENV valueVAL/></qemu:commandline></domain>"…

13、输入捕获实验

目录 一、通用定时器输入捕获概述 二、常用寄存器和库函数配置 三、输入捕获实验讲解 一、通用定时器输入捕获概述 STM32输入捕获工作过程&#xff08;通道1为例&#xff09; 一句话总结工作过程&#xff1a; 通过检测TIMx_CHx上的边沿信号&#xff0c;在边沿信号发生跳变…

28.HarmonyOS App(JAVA)多页签的实现(Tab)

HarmonyOS App(JAVA)多页签的实现&#xff08;Tab&#xff09; 页面可左右滑动&#xff0c;点击界面1,2,3切换到对应界面 PageSlider的创建和使用 在layout目录下的xml文件中创建PageSlider。 <PageSlider ohos:id"$id:page_slider" ohos:height"300vp&…

2D割草/吸血鬼游戏 性能优化——GPU Spine动画

视频中万人同屏方案(gpu动画、渲染、索敌、避障等功能)&#xff0c;可某宝搜店铺&#xff1a;【游戏开发资源商店】获取整套方案源码。 在过去的几年里&#xff0c;割草、类吸血鬼玩法的游戏频出爆款&#xff0c;其丰富的技能、满屏特效、刷怪清屏的解压畅快是此类游戏的核心&…

【MySQL】复合查询(重点)-- 详解

一、基本查询练习回顾 1、查询工资高于 500 或岗位为 MANAGER 的雇员&#xff0c;同时还要满足他们的姓名首字母为大写的 J 2、按照部门号升序而雇员的工资降序排序 3、使用年薪进行降序排序 4、显示工资最高的员工的名字和工作岗位 5、显示工资高于平均工资的员工信息 6、显…

韦东山嵌入式Liunx入门驱动开发四

文章目录 一、异常与中断的概念及处理流程1-1 中断的引入1-2 栈(1) CPU实现a ab的过程(2) 进程与线程 1-3 Linux系统对中断处理的演进1-4 Linux 中断系统中的重要数据结构(1) irq_desc 结构体(2) irqaction 结构体(3) irq_data 结构体(4) irq_domain 结构体(5) irq_domain 结构…

Redis入门与应用

Redis入门与应用 Redis的技术全景 Redis一个开源的基于键值对&#xff08;Key-Value&#xff09;NoSQL数据库。使用ANSI C语言编写、支持网络、基于内存但支持持久化。性能优秀&#xff0c;并提供多种语言的API。 两大维度 两大维度&#xff1a;应用维度、底层原理维度 我们…

记一次dockerfile无法构建问题追溯

我有一个dockerfile如下&#xff1a; ENTRYPOINT ["/sbin/tini"&#xff0c;"-g", "--"] CMD /home/scrapy/start.sh 我原本的用意是先启动tini&#xff0c;再执行下面的cmd命令启动start.sh。 为啥要用tini&#xff1f; 因为我的这个docker…

git介绍4.2

git(版本控制工具) 一、git 介绍 1、git是目前世界上最先进的分布式版本控制系统&#xff0c;可以有效&#xff0c;高速的处理从小到大的项目版本管理。 2、git是linux torvalds 为了帮助管理linux内核开发二开发的一个开放源码的版本控制软件。 3、git作用&#xff1a;更好…

PageHelper开源框架解读

在使用springboot开发系统时&#xff0c;列表查询经常会用PageHelper来进行分页。使用起来很方便&#xff0c;但从未想过它的实现原理&#xff0c;所以对其进行解读。 Service public class ScUserServiceImpl extends ServiceImpl<ScUserMapper, ScUser> implements IS…

WIN10 无密码自动登录

1、家里重装了一下WIN10系统&#xff0c;第一次登陆居然用了微软网站账号&#xff0c;结果密码忘记了&#xff0c;后面只能用PIN码登陆系统。 2、需要登录微软的网站修改密码&#xff1a; Microsoft account | Sign In or Create Your Account Today – Microsoft 3、在运行…

APP自动化测试-入门示例

入门示例 通过上一篇博客APP自动化测试介绍-CSDN博客的学习&#xff0c;相信大家对APP自动化测试已经有了一定的了解&#xff0c;下面演示一下入门示例 1. 配置Appium 1.1. 点击Appium图标&#xff0c;打开服务器&#xff1a; 1.2. 点击Edit Configurations,进入配置页面&am…

【LeetCode】【滑动窗口长度不固定】978 最长湍流子数组

1794.【软件认证】最长的指定瑕疵度的元音子串 这个例题&#xff0c;是滑动窗口中长度不定求最大的题目&#xff0c;在看题之前可以先看一下【leetcode每日一题】【滑动窗口长度不固定】案例。 题目描述 定义&#xff1a;开头和结尾都是元音字母&#xff08;aeiouAEIOU&…

GIT基本的命令

文章目录 04.GIT本地操作-初始化工作区内容小结 05.GIT本地操作-add与commit目标内容小结 06.GIT本地操作-差异比较目标内容小结 07.GIT本地操作-版本回退目标内容小结 08.GIT本地操作-修改撤消目标内容小结 09.GIT本地操作-总结 04.GIT本地操作-初始化工作区 内容 初始化工作…

Java对象大小计算

概述 在实际应用中&#xff0c;尤其是在进行JVM调优时&#xff0c;理解并正确估计对象大小是非常重要的&#xff0c;因为这直接影响到内存分配、垃圾回收效率以及应用程序的整体性能。 对象的组成 在Java中&#xff0c;计算一个对象的大小是为了了解它在内存中占用的确切空间…

第十五天-爬虫项目实战

目录 1.介绍 2.代码 1.main.py 2.PageSider.py 3.DetailSpider.py 4.DataParse.py 5.Constant.py 6.HanderRequest.py 1.介绍 1. 使用多线程爬取网站 2.爬取数据后保存至excel 3.爬取网站(仅做测试)网创类项目爬取&#xff1a;https://www.maomp.com/ 4..实现效果 …