【易客吧】_全网激活码总代_激活码商城

您现在的位置是:首页 > 热门资讯 > 正文

热门资讯

揭秘 Java 中 AES 加密的强大功能 (揭秘java虚拟机)

用户投稿2024-04-19热门资讯19

引言

高级加密标准 (AES) 是一种对称块密码,是当今使用最广泛的加密算法之一。Java 编程语言提供了对 AES 加密算法的内置支持,允许开发人员轻松加密和解密数据。本文将深入探究Java 中 AES 加密的强大功能,包括其工作原理、实现方式以及各种应用场景。

AES 加密的原理

AES 加密是一种分块密码算法,其工作原理如下:明文分组:待加密数据被分成固定大小的分组,通常为 128 位。密钥扩展:密钥被扩展为称为密钥计划的一组子密钥。加密轮次:每一轮加密都对明文分组执行一系列操作,包括替换字节、行移位和列混合。最终轮:最后一轮加密使用不同的操作顺序。密文分组:经过多次加密轮次后,获得密文分组。总共有 9、11 或 13 轮加密轮次,取决于密钥长度为 128、192 或 256 位。

Java 中 AES 加密的实现

Java 提供了 `javax.crypto` 包,其中包含用于 AES 加密的类。主要类包括:Cipher:执行加密和解密操作。KeyGenerator:生成 AES 密钥。SecretKey:表示 AES 密钥。IvParameterSpec:指定初始向量,在某些模式下使用。以下是使用 Java 进行 AES 加密的步骤:1. 生成一个 AES 密钥。2. 创建一个 Cipher 实例,指定加密模式和填充方式。3. 初始化 Cipher,使用密钥和初始向量(如果需要)。4. 加密明文分组,并将结果存储在字节数组中。5. 将密文分组转换为所需格式,例如 Base64 编码字符串。

AES 加密的常见模式

Java 支持以下 AES 加密模式:ECB(电子密码本模式):每个明文分组单独加密,不依赖于其他分组。CBC(密码块链接模式):每个密文分组与前一个密文分组进行异或运算。CFB(密码反馈模式):使用前一个密文分组作为密钥流的一部分。OFB(输出反馈模式):使用前一个密文分组生成密钥流。选择合适的模式取决于安全性、性能和应用场景等因素。

AES 加密的应用场景

AES 加密在 Java 中广泛用于各种应用程序,包括:文件加密:保护存储在文件系统上的敏感数据。数据库加密:加密存储在数据库中的数据,防止未经授权的访问。网络通信加密:在客户端和服务器之间加密通信数据,确保传输过程中的保密性。密码存储:使用 AES 加密安全地存储用户密码。数字签名验证:使用 AES 密钥生成数字签名,以验证消息的完整性和出处。

示例代码

以下 Java 代码示例展示了如何使用 AES 加密:```javaimport javax.crypto.;import javax.crypto.spec.;public class AESEncryption {public static void main(String[] args) throws Exception {// 明文String plaintext = "Hello, World!";// 密钥byte[] key = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };// 初始化 AES 密钥SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");// 创建 Cipher 实例Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");// 初始化 Cipher,使用 ECB 模式cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);// 加密明文byte[] ciphertext = cipher.doFinal(plaintext.getBytes());// 转换为 Base64 编码字符串String base64Ciphertext = Base64.getEncoder().encodeToString(ciphertext);// 打印密文System.out.println("密文:" + base64Ciphertext);}}```

结论

Java 中的 AES 加密是一种强大的工具,可以保护数据的机密性。通过利用 Java 提供的 `javax.crypto` 包,开发人员可以轻松实现 AES 加密并将其集成到各种应用程序中。了解 AES 加密的原理、实现方式和应用场景,对于确保数据的安全至关重要。

如何使用java对密码加密 加密方式aes

Java有相关的实现类:具体原理如下对于任意长度的明文,AES首先对其进行分组,每组的长度为128位。 分组之后将分别对每个128位的明文分组进行加密。 对于每个128位长度的明文分组的加密过程如下:(1)将128位AES明文分组放入状态矩阵中。 (2)AddRoundKey变换:对状态矩阵进行AddRoundKey变换,与膨胀后的密钥进行异或操作(密钥膨胀将在实验原理七中详细讨论)。 (3)10轮循环:AES对状态矩阵进行了10轮类似的子加密过程。 前9轮子加密过程中,每一轮子加密过程包括4种不同的变换,而最后一轮只有3种变换,前9轮的子加密步骤如下:●SubBytes变换:SubBytes变换是一个对状态矩阵非线性的变换;●ShiftRows变换:ShiftRows变换对状态矩阵的行进行循环移位;●MixColumns变换:MixColumns变换对状态矩阵的列进行变换;●AddRoundKey变换:AddRoundKey变换对状态矩阵和膨胀后的密钥进行异或操作。 最后一轮的子加密步骤如下:●SubBytes变换:SubBytes变换是一个对状态矩阵非线性的变换;●ShiftRows变换:ShiftRows变换对状态矩阵的行进行循环移位;●AddRoundKey变换:AddRoundKey变换对状态矩阵和膨胀后的密钥进行异或操作;(4)经过10轮循环的状态矩阵中的内容就是加密后的密文。 AES的加密算法的伪代码如下。 在AES算法中,AddRoundKey变换需要使用膨胀后的密钥,原始的128位密钥经过膨胀会产生44个字(每个字为32位)的膨胀后的密钥,这44个字的膨胀后的密钥供11次AddRoundKey变换使用,一次AddRoundKey使用4个字(128位)的膨胀后的密钥。 三.AES的分组过程对于任意长度的明文,AES首先对其进行分组,分组的方法与DES相同,即对长度不足的明文分组后面补充0即可,只是每一组的长度为128位。 AES的密钥长度有128比特,192比特和256比特三种标准,其他长度的密钥并没有列入到AES联邦标准中,在下面的介绍中,我们将以128位密钥为例。 四.状态矩阵状态矩阵是一个4行、4列的字节矩阵,所谓字节矩阵就是指矩阵中的每个元素都是一个1字节长度的数据。 我们将状态矩阵记为State,State中的元素记为Sij,表示状态矩阵中第i行第j列的元素。 128比特的明文分组按字节分成16块,第一块记为“块0”,第二块记为“块1”,依此类推,最后一块记为“块15”,然后将这16块明文数据放入到状态矩阵中,将这16块明文数据放入到状态矩阵中的方法如图2-2-1所示。 块0块4块8块12块1块5块9块13块2块6块10块14块3块7块11块15图2-2-1将明文块放入状态矩阵中五.AddRoundKey变换状态矩阵生成以后,首先要进行AddRoundKey变换,AddRoundKey变换将状态矩阵与膨胀后的密钥进行按位异或运算,如下所示。 其中,c表示列数,数组W为膨胀后的密钥,round为加密轮数,Nb为状态矩阵的列数。 它的过程如图2-2-2所示。 图2-2-2AES算法AddRoundKey变换六.10轮循环经过AddRoundKey的状态矩阵要继续进行10轮类似的子加密过程。 前9轮子加密过程中,每一轮要经过4种不同的变换,即SubBytes变换、ShiftRows变换、MixColumns变换和AddRoundKey变换,而最后一轮只有3种变换,即SubBytes变换、ShiftRows变换和AddRoundKey变换。 AddRoundKey变换已经讨论过,下面分别讨论余下的三种变换。 1.SubBytes变换SubBytes是一个独立作用于状态字节的非线性变换,它由以下两个步骤组成:(1)在GF(28)域,求乘法的逆运算,即对于α∈GF(28)求β∈GF(28),使αβ =βα = 1mod(x8 + x4 + x3 + x + 1)。 (2)在GF(28)域做变换,变换使用矩阵乘法,如下所示:由于所有的运算都在GF(28)域上进行,所以最后的结果都在GF(28)上。 若g∈GF(28)是GF(28)的本原元素,则对于α∈GF(28),α≠0,则存在β ∈ GF(28),使得:β = gαmod(x8 + x4 + x3 + x + 1)由于g255 = 1mod(x8 + x4 + x3 + x + 1)所以g255-α = β-1mod(x8 + x4 + x3 + x + 1)根据SubBytes变换算法,可以得出SubBytes的置换表,如表2-2-1所示,这个表也叫做AES的S盒。 该表的使用方法如下:状态矩阵中每个元素都要经过该表替换,每个元素为8比特,前4比特决定了行号,后4比特决定了列号,例如求SubBytes(0C)查表的0行C列得FE。 表2-2-1AES的SubBytes置换表它的变换过程如图2-2-3所示。 图2-2-3SubBytes变换AES加密过程需要用到一些数学基础,其中包括GF(2)域上的多项式、GF(28)域上的多项式的计算和矩阵乘法运算等,有兴趣的同学请参考相关的数学书籍。 2.ShiftRows变换ShiftRows变换比较简单,状态矩阵的第1行不发生改变,第2行循环左移1字节,第3行循环左移2字节,第4行循环左移3字节。 ShiftRows变换的过程如图2-2-4所示。 图2-2-4AES的ShiftRows变换3.MixColumns变换在MixColumns变换中,状态矩阵的列看作是域GF(28)的多项式,模(x4+1)乘以c(x)的结果:c(x)=(03)x3+(01)x2+(01)x+(02)这里(03)为十六进制表示,依此类推。 c(x)与x4+1互质,故存在逆:d(x)=(0B)x3+(0D)x2+(0G)x+(0E)使c(x)•d(x) = (D1)mod(x4+1)。 设有:它的过程如图2-2-5所示。 图2-2-5AES算法MixColumns变换七.密钥膨胀在AES算法中,AddRoundKey变换需要使用膨胀后的密钥,膨胀后的密钥记为子密钥,原始的128位密钥经过膨胀会产生44个字(每个字为32位)的子密钥,这44个字的子密钥供11次AddRoundKey变换使用,一次AddRoundKey使用4个字(128位)的膨胀后的密钥。 密钥膨胀算法是以字为基础的(一个字由4个字节组成,即32比特)。 128比特的原始密钥经过膨胀后将产生44个字的子密钥,我们将这44个密钥保存在一个字数组中,记为W[44]。 128比特的原始密钥分成16份,存放在一个字节的数组:Key[0],Key[1]……Key[15]中。 在密钥膨胀算法中,Rcon是一个10个字的数组,在数组中保存着算法定义的常数,分别为:Rcon[0] = 0xRcon[1] = 0xRcon[2] = 0xRcon[3] = 0xRcon[4] = 0xRcon[5] = 0xRcon[6] = 0xRcon[7] = 0xRcon[8] = 0x1bRcon[9] = 0x另外,在密钥膨胀中包括其他两个操作RotWord和SubWord,下面对这两个操作做说明:RotWord( B0,B1,B2,B3 )对4个字节B0,B1,B2,B3进行循环移位,即RotWord( B0,B1,B2,B3 ) = ( B1,B2,B3,B0 )SubWord( B0,B1,B2,B3 )对4个字节B0,B1,B2,B3使用AES的S盒,即SubWord( B0,B1,B2,B3 ) = ( B’0,B’1,B’2,B’3 )其中,B’i = SubBytes(Bi),i = 0,1,2,3。 密钥膨胀的算法如下:八.解密过程AES的加密和解密过程并不相同,首先密文按128位分组,分组方法和加密时的分组方法相同,然后进行轮变换。 AES的解密过程可以看成是加密过程的逆过程,它也由10轮循环组成,每一轮循环包括四个变换分别为InvShiftRows变换、InvSubBytes变换、InvMixColumns变换和AddRoundKey变换;这个过程可以描述为如下代码片段所示:九.InvShiftRows变换InvShiftRows变换是ShiftRows变换的逆过程,十分简单,指定InvShiftRows的变换如下。 Sr,(c+shift(r,Nb))modNb= Sr,c for 0 < r< 4 and 0 ≤ c < Nb图2-2-6展示了这个过程。 图2-2-6AES算法InvShiftRows变换十.InvSubBytes变换InvSubBytes变换是SubBytes变换的逆变换,利用AES的S盒的逆作字节置换,表2-2-2为InvSubBytes变换的置换表。 表2-2-2InvSubBytes置换表十一.InvMixColumns变换InvMixColumns变换与MixColumns变换类似,每列乘以d(x)d(x) = (OB)x3 + (0D)x2 + (0G)x + (0E)下列等式成立:( (03)x3 + (01)x2 + (01)x + (02) )⊙d(x) = (01)上面的内容可以描述为以下的矩阵乘法:十二.AddRoundKey变换AES解密过程的AddRoundKey变换与加密过程中的AddRoundKey变换一样,都是按位与子密钥做异或操作。 解密过程的密钥膨胀算法也与加密的密钥膨胀算法相同。 最后状态矩阵中的数据就是明文。

JAVA虚拟机是什么

Java虚拟机(JavaVirtualMachine)简称JVMJava虚拟机是一个想象中的机器,在实际的计算机上通过软件模拟来实现。 Java虚拟机有自己想象中的硬件,如处理器、堆栈、寄存器等,还具有相应的指令系统。 Java虚拟机(JVM)一种用于计算设备的规范,可用不同的方式(软件或硬件)加以实现。 编译虚拟机的指令集与编译微处理器的指令集非常类似。 Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个废品回收堆和一个存储方法域。 Java虚拟机(JVM)是可运行Java代码的假想计算机。 只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的任何Java代码能够在该系统上运行。 Java虚拟机是一个想象中的机器,在实际的计算机上通过软件模拟来实现。 Java虚拟机有自己想象中的硬件,如处理器、堆栈、寄存器等,还具有相应的指令系统。

什么是Java虚拟机?

虚拟机是一种抽象化的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的。

Java虚拟机有自己完善的硬体架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。

这种解释应该算是正确的,但是只描述了虚拟机的外部行为和功能,并没有针对内部原理做出说明。一般情况下我们不需要知道虚拟机的运行原理,只要专注写java代码就可以了,这也正是虚拟机之所以存在的原因--屏蔽底层操作系统平台的不同并且减少基于原生语言开发的复杂性,使java这门语言能够跨各种平台(只要虚拟机厂商在特定平台上实现了虚拟机),并且简单易用。这些都是虚拟机的外部特性,但是从这些信息来解释虚拟机,未免太笼统了,无法让我们知道内部原理。

从进程的角度解释JVM

让我们尝试从操作系统的层面来理解虚拟机。我们知道,虚拟机是运行在操作系统之中的,那么什么东西才能在操作系统中运行呢?当然是进程,因为进程是操作系统中的执行单位。可以这样理解,当它在运行的时候,它就是一个操作系统中的进程实例,当它没有在运行时(作为可执行文件存放于文件系统中),可以把它叫做程序。

对命令行比较熟悉的同学,都知道其实一个命令对应一个可执行的二进制文件,当敲下这个命令并且回车后,就会创建一个进程,加载对应的可执行文件到进程的地址空间中,并且执行其中的指令。下面对比C语言和Java语言的HelloWorld程序来说明问题。

首先编写C语言版的HelloWorld程序。

编译C语言版的HelloWorld程序:

gcc HelloWorld.c -o HelloWorld运行C语言版的HelloWorld程序:

zhangjg@linux:/deve/workspace/HelloWorld/src$ ./HelloWorld hello world

gcc编译器编译后的文件直接就是可被操作系统识别的二进制可执行文件,当我们在命令行中敲下 ./HelloWorld这条命令的时候, 直接创建一个进程, 并且将可执行文件加载到进程的地址空间中, 执行文件中的指令。

作为对比, 我们看一下Java版HelloWord程序的编译和执行形式。

首先编写源文件 :

编译Java版的HelloWorld程序:

运行Java版的HelloWorld程序:

zhangjg@linux:/deve/workspace/HelloJava/src$ java -classpath . HelloWorld HelloWorld从上面的过程可以看到, 我们在运行Java版的HelloWorld程序的时候, 敲入的命令并不是 ./ 。 因为class文件并不是可以直接被操作系统识别的二进制可执行文件 。 我们敲入的是java这个命令。 这个命令说明, 我们首先启动的是一个叫做java的程序, 这个java程序在运行起来之后就是一个JVM进程实例。

上面的命令执行流程是这样的:java命令首先启动虚拟机进程,虚拟机进程成功启动后,读取参数“HelloWorld”,把他作为初始类加载到内存,对这个类进行初始化和动态链接(关于类的初始化和动态链接会在后面的博客中介绍),然后从这个类的main方法开始执行。也就是说我们的文件不是直接被系统加载后直接在cpu上执行的,而是被一个叫做虚拟机的进程托管的。首先必须虚拟机进程启动就绪,然后由虚拟机中的类加载器加载必要的class文件,包括jdk中的基础类(如String和Object等),然后由虚拟机进程解释class字节码指令,把这些字节码指令翻译成本机cpu能够识别的指令,才能在cpu上运行。

从这个层面上来看,在执行一个所谓的java程序的时候,真真正正在执行的是一个叫做Java虚拟机的进程,而不是我们写的一个个的class文件。这个叫做虚拟机的进程处理一些底层的操作,比如内存的分配和释放等等。我们编写的class文件只是虚拟机进程执行时需要的“原料”。这些“原料”在运行时被加载到虚拟机中,被虚拟机解释执行,以控制虚拟机实现我们java代码中所定义的一些相对高层的操作,比如创建一个文件等,可以将class文件中的信息看做对虚拟机的控制信息,也就是一种虚拟指令。

编程语言也有自己的原理, 学习一门语言, 主要是把它的原理搞明白。 看似一个简单的HelloWorld程序, 也有很多深入的内容值得剖析。

揭秘 Java 中 AES 加密的强大功能 (揭秘java虚拟机) 第1张

JVM体系结构简介

为了展示虚拟机进程和class文件的关系,特意画了下面一张图:

根据上图表达的内容,我们编译之后的class文件是作为Java虚拟机的原料被输入到Java虚拟机的内部的,那么具体由谁来做这一部分工作呢?其实在Java虚拟机内部,有一个叫做类加载器的子系统,这个子系统用来在运行时根据需要加载类。注意上面一句话中的“根据需要”四个字。在Java虚拟机执行过程中,只有他需要一个类的时候,才会调用类加载器来加载这个类,并不会在开始运行时加载所有的类。就像一个人,只有饿的时候才去吃饭,而不是一次把一年的饭都吃到肚子里。一般来说,虚拟机加载类的时机,在第一次使用一个新的类的时候。本专栏后面的文章会具体讨论Java中的类加载器。

由虚拟机加载的类,被加载到Java虚拟机内存中之后,虚拟机会读取并执行它里面存在的字节码指令。虚拟机中执行字节码指令的部分叫做执行引擎。就像一个人,不是把饭吃下去就完事了,还要进行消化,执行引擎就相当于人的肠胃系统。在执行的过程中还会把各个class文件动态的连接起来。关于执行引擎的具体行为和动态链接相关的内容也会在本专栏后续的文章中进行讨论。

我们知道,Java虚拟机会进行自动内存管理。具体说来就是自动释放没有用的对象,而不需要程序员编写代码来释放分配的内存。这部分工作由废品收集子系统负责。

从上面的论述可以知道, 一个Java虚拟机实例在运行过程中有三个子系统来保障它的正常运行,分别是类加载器子系统, 执行引擎子系统和废品收集子系统。 如下图所示:

虚拟机的运行,必须加载class文件,并且执行class文件中的字节码指令。它做这么多事情,必须需要自己的空间。就像人吃下去的东西首先要放在胃中。虚拟机也需要空间来存放个中数据。首先,加载的字节码,需要一个单独的内存空间来存放;一个线程的执行,也需要内存空间来维护方法的调用关系,存放方法中的数据和中间计算结果;在执行的过程中,无法避免的要创建对象,创建的对象需要一个专门的内存空间来存放。关于虚拟机运行时数据区的内容,也会出现在本专栏后续的文章中。虚拟机的运行时内存区大概可以分成下图所示的几个部分。(这里只是大概划分,并没有划分的很精细)

总结

写到这里,基本上关于我对java虚拟机的理解就写完了。这篇文章的主题虽然是深入理解Java虚拟机,但是你可能感觉一点也不“深入”,也只是泛泛而谈。我也有这样的感觉。限于自己水平有限,也只能这样了,要是想深入理解java虚拟机,强烈建议读一下三本书:

《深入Java虚拟机》

《深入理解Java虚拟机JVM高级特性与最佳实践》

《Java虚拟机规范》

其实我也读过这几本书,但是它们对虚拟机的解释也是基于一个外部模型,而没有深入剖析虚拟机内部的实现原理。虚拟机是一个大而复杂的东西,实现虚拟机的人都是大牛级别的,如果不是参与过虚拟机的实现,应该很少有人能把它参透。本专栏后面的一些文章也参考了这三本书, 虽然讲解Java语法的书不计其数, 但是深入讲解虚拟机的书, 目前为止我就见过这三本,并且网上的资料也不是很多。

最后做一个总结:

1 虚拟机并不神秘,在操作系统的角度看来,它只是一个普通进程。

2 这个叫做虚拟机的进程比较特殊,它能够加载我们编写的class文件。如果把JVM比作一个人,那么class文件就是我们吃的食物。

3 加载class文件的是一个叫做类加载器的子系统。就好比我们的嘴巴,把食物吃到肚子里。

4 虚拟机中的执行引擎用来执行class文件中的字节码指令。就好比我们的肠胃,对吃进去的食物进行消化。

5 虚拟机在执行过程中,要分配内存创建对象。当这些对象过时无用了,必须要自动清理这些无用的对象。清理对象回收内存的任务由废品收集器负责。就好比人吃进去的食物,在消化之后,必须把废物排出体外,腾出空间可以在下次饿的时候吃饭并消化食物。

扩展资料:

关于JAVA虚拟机的参数说明如下:

1、运行class文件

执行带main方法的class文件,Java虚拟机[3]命令参数行为:

java <CLASS文件名>

注意:CLASS文件名不要带文件后缀

例如:

如果执行的class文件是带包的,即在类文件中使用了:

package <;包名>

那应该在包的基路径下执行,Java虚拟机命令行参数:

java <;包名>文件名

例如:

中,其包名为,对应的语句为:

及编译后的class文件的存放目录如下:

要运行,应在classes目录下执行:

2、运行jar文件中的class

原理和运行class文件一样,只需加上参数-cp <jar文件名>;即可。

例如:执行中的类,命令行如下:

3、显示JDK版本信息

当一台机器上有多个jdk版本时,需要知道当前使用的是那个版本的jdk,使用参数-version即可知道其版本,命令行为:

java -version

4、增加虚拟机可以使用的最大内存

Java虚拟机可使用的最大内存是有限制的,缺省值通常为64MB或128MB。

如果一个应用程序为了提高性能而把数据加载内存中而占用较大的内存,比如超过了默认的最大值128MB,需要加大java虚拟机可使用的最大内存,否则会出现Out of Memory的异常。启动java时,需要使用如下两个参数:

-Xms java虚拟机初始化时使用的内存大小

-Xmx java虚拟机可以使用的最大内存

以上两个命令行参数中设置的size,可以带单位,例如:256m表示256MB

举例说明:

java -Xms128m -Xmx256m ...

表示Java虚拟机初始化时使用的内存为128MB,可使用的最大内存为256MB。

对于tomcat,可以修改其脚本catalina. sh(Unix平台)或(Windows平台),设置变量JAVA_OPTS即可,例如:

JAVA_OPTS=-Xms128m -Xmx256m

参考资料:网络百科-java虚拟机

若对本页面资源感兴趣,请点击下方或右方图片,注册登录后

搜索本页相关的【资源名】【软件名】【功能词】或有关的关键词,即可找到您想要的资源

如有其他疑问,请咨询右下角【在线客服】,谢谢支持!

揭秘 Java 中 AES 加密的强大功能 (揭秘java虚拟机) 第2张

发表评论

评论列表

  • 这篇文章还没有收到评论,赶紧来抢沙发吧~
欢迎你第一次访问网站!