对称密码体制
- 格式:doc
- 大小:398.46 KB
- 文档页数:16
对称密码体制和非对称密码体制一、对称加密(Symmetric Key Encryption)对称加密是最快速、最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key)。
对称加密有很多种算法,由于它效率很高,所以被广泛使用在很多加密协议的核心当中。
自1977年美国颁布DES(Data Encryption Standard)密码算法作为美国数据加密标准以来,对称密码体制迅速发展,得到了世界各国的关注和普遍应用。
对称密码体制从工作方式上可以分为分组加密和序列密码两大类。
对称加密算法的优点:算法公开、计算量小、加密速度快、加密效率高。
对称加密算法的缺点:交易双方都使用同样钥匙,安全性得不到保证。
此外,每对用户每次使用对称加密算法时,都需要使用其他人不知道的惟一钥匙,这会使得发收信双方所拥有的钥匙数量呈几何级数增长,密钥管理成为用户的负担。
对称加密算法在分布式网络系统上使用较为困难,主要是因为密钥管理困难,使用成本较高。
而与公开密钥加密算法比起来,对称加密算法能够提供加密和认证却缺乏了签名功能,使得使用范围有所缩小。
对称加密通常使用的是相对较小的密钥,一般小于256 bit。
因为密钥越大,加密越强,但加密与解密的过程越慢。
如果你只用1 bit来做这个密钥,那黑客们可以先试着用0来解密,不行的话就再用1解;但如果你的密钥有1 MB大,黑客们可能永远也无法破解,但加密和解密的过程要花费很长的时间。
密钥的大小既要照顾到安全性,也要照顾到效率,是一个trade-off。
分组密码:也叫块加密(block cyphers),一次加密明文中的一个块。
是将明文按一定的位长分组,明文组经过加密运算得到密文组,密文组经过解密运算(加密运算的逆运算),还原成明文组,有 ECB、CBC、CFB、OFB 四种工作模式。
序列密码:也叫流加密(stream cyphers),一次加密明文中的一个位。
对称密码体制与公钥密码体制是现代密码学中两种基本的密码体制,它们在保护信息安全,防止信息被未经授权者获取和篡改方面发挥着重要的作用。
下面将从定义、特点、优缺点、应用领域等方面来详细描述对称密码体制与公钥密码体制。
一、对称密码体制1. 定义:对称密码体制是指加密和解密使用同一个密钥的密码系统,也就是通信双方需要共享同一个密钥来进行加解密操作。
2. 特点:对称密码体制具有以下特点:1) 加密速度快:因为加密和解密使用同一个密钥,所以运算速度快。
2) 安全性依赖于密钥的安全性:只要密钥泄露,整个系统的安全就会受到威胁。
3) 密钥管理困难:通信双方需要事先共享密钥,密钥的分发和管理是一个很复杂的问题。
3. 优缺点:对称密码体制的优缺点如下:1) 优点:加密速度快,适合对大数据进行加密;算法简单,易于实现和设计。
2) 缺点:密钥管理困难,安全性依赖于密钥的安全性。
4. 应用领域:对称密码体制主要应用于一些对加密速度要求较高,密钥管理相对容易的场景中,比如网络通信、数据库加密等领域。
二、公钥密码体制1. 定义:公钥密码体制是指加密和解密使用不同密钥的密码系统,也就是通信双方分别有公钥和私钥,公钥用于加密,私钥用于解密。
2. 特点:公钥密码体制具有以下特点:1) 加密和解密使用不同的密钥,安全性更高。
2) 密钥管理相对容易:每个用户都拥有自己的一对密钥,不需要事先共享密钥。
3) 加密速度较慢:因为加密和解密使用不同的密钥,计算复杂度较高。
3. 优缺点:公钥密码体制的优缺点如下:1) 优点:安全性更高,密钥管理相对容易。
2) 缺点:加密速度较慢,算法复杂,设计和实现难度大。
4. 应用领域:公钥密码体制主要应用于对安全性要求较高,加密速度要求相对较低的场景中,比如数字签名、安全传输等领域。
三、对称密码体制与公钥密码体制的比较根据对称密码体制与公钥密码体制的特点、优缺点和应用领域,下面对它们进行比较:1. 安全性:公钥密码体制的安全性更高,因为加密和解密使用不同的密钥,不容易受到攻击;而对称密码体制的安全性依赖于密钥的安全性,一旦密钥泄露,整个系统的安全将受到威胁。
《应用密码学》习题和思考题答案第5章 对称密码体制5-1 画出分组密码算法的原理框图,并解释其基本工作原理。
答:图5-1 分组密码原理框图1210-t 1210-t )分组密码处理的单位是一组明文,即将明文消息编码后的数字序列im m m m ,,,,210 划分成长为L 位的组()0121,,,,L m m m m m -=,各个长为L 的分组分别在密钥()0121,,,,t k k k k k -= (密钥长为t )的控制下变换成与明文组等长的一组密文输出数字序列()0121,,,,L c c c c c -= 。
L 通常为64或128。
解密过程是加密的逆过程。
5-2 为了保证分组密码算法的安全强度,对分组密码算法的要求有哪些? 答:(1)分组长度足够大;(2)密钥量足够大;(3)密码变换足够复杂。
5-3 什么是SP 网络?答:SP 网络就是由多重S 变换和P 变换组合成的变换网络,即迭代密码,它是乘积密码的一种,由Shannon 提出。
其基本操作是S 变换(代替)和P 变换(换位),前者称为S 盒,后者被称为P 盒。
S 盒的作用是起到混乱作用,P 盒的作用是起到扩散的作用。
5-4 什么是雪崩效应?答:雪崩效应是指输入(明文或密钥)即使只有很小的变化,也会导致输出发生巨大变化的现象。
即明文的一个比特的变化应该引起密文许多比特的改变。
5-5 什么是Feistel 密码结构?Feistel 密码结构的实现依赖的主要参数有哪些? 答:1K nK i密文明文图5-6 Feistel密码结构Feistel 密码结构如图5-6所示。
加密算法的输入是长为2w 位的明文和密钥K ,明文被均分为长度为w 位的0L 和0R 两部分。
这两部分经过n 轮迭代后交换位置组合在一起成为密文。
其运算逻辑关系为:1(1,2,,)i i L R i n -==11(,)(1,2,,)i i i i R L F R K i n --=⊕=每轮迭代都有相同的结构。
对称密钥密码体制的原理和特点一、对称密钥密码体制的原理1. 对称密钥密码体制是一种加密方式,使用相同的密钥进行加密和解密。
2. 在对称密钥密码体制中,加密和解密使用相同的密钥,这个密钥必须保密,只有合法的用户才能知道。
3. 对称密钥密码体制使用单一密钥,因此在加密和解密过程中速度较快。
4. 对称密钥密码体制中,发送者和接收者必须共享同一个密钥,否则无法进行加密和解密操作。
二、对称密钥密码体制的特点1. 高效性:对称密钥密码体制使用单一密钥进行加密和解密,因此速度较快,适合于大量数据的加密和解密操作。
2. 安全性有限:尽管对称密钥密码体制的速度较快,但密钥的安全性存在一定的风险。
一旦密钥泄露,加密数据可能会遭到破解,因此密钥的安全性对于对称密钥密码体制至关重要。
3. 密钥分发困难:在对称密钥密码体制中,发送者和接收者必须共享同一个密钥,因此密钥的分发和管理可能会存在一定的困难。
4. 密钥管理困难:对称密钥密码体制密钥的管理和分发往往需要借助第三方机构或者密钥协商协议来实现,这增加了密钥管理的复杂性。
5. 广泛应用:尽管对称密钥密码体制存在一定的安全性和管理困难,但由于其高效性,仍然广泛应用于网络通信、金融交易等领域。
对称密钥密码体制是一种加密方式,使用相同的密钥进行加密和解密。
它具有高效性和广泛应用的特点,然而安全性较差并且密钥管理困难。
在实际应用中,需要权衡其优劣势,并采取相应的安全措施来确保其安全性和有效性。
对称密钥密码体制的应用对称密钥密码体制作为一种快速高效的加密方式,在现实生活中有着广泛的应用。
主要的应用领域包括网络通信和数据传输、金融交易、安全存储、以及移动通信等。
1. 网络通信和数据传输在网络通信和数据传输中,对称密钥密码体制被广泛应用于加密数据传输过程。
在互联网传输中,大量的数据需要在用户和服务器之间进行传输,为了保护数据的安全性,对称密钥密码体制被用来加密数据,确保传输过程中数据不被窃取或篡改。
第九章密码技术9-1 简述对称密钥密码体制、非对称密钥密码体制的第九章密码技术与压缩技术9-1 简述对称密钥密码体制、非对称密钥密码体制的加密原理和各自的特点。
对称密码体制的加密方式可分为:(1)序列密码,。
它的主要原理是:通过有限状态机制产生性能优良的伪随机序列,使用该序列加密信息流,得到密文序列。
(2)分组密码。
分组密码的工作方式是将明文分成固定长度的组,用同一密钥和算法对每一块加密,输出也是固定长度的密文。
其主要特点:加解密双方在加解密过程中要使用完全相同或本质上等同的密钥。
非对称密钥密码体制的加密原理:在加密过程中,密钥被分解为一对。
这对密钥中的任何一把都可作为公开密钥通过非保密方式向他人公开,用于对信息的加密;而另一把则作为则私有密钥进行保存,用于对加密信息的解密。
其特点有:具有较强的保密功能,还克服了密钥发布的问题,并具有鉴别功能。
9-2 为什么说混合加密体制是保证网络上传输信息的安全的一种较好的可行方法,混合加密体制采用公开密钥密码技术在通信双方之间建立连接,包括双方的认证过程以及密钥的交换(传送秘密密钥),在连接建立以后,双有可以使用对称加密技术对实际传输的数据进行加密解密。
这样既解决了密钥分发的困难,又解决了加、解密的速度和效率问题,是目前解决网络上传输信息安全的一种较好的可行方法。
9-3 简述链路加密、节点加密和端对端加密等三种加密方式的特点。
链路加密方式只对通信链路中的数据加密,而不对网络节点内的数据加密。
使用链路加密装置能为链路上的所有报文提供传输服务:即经过一台节点机的所有网络信息传输均需加、解密,每一个经过的节点都必须有加密装置,以便解密、加密报文。
节点加密方式在中间节点里装有用于加、解密的保护装置,即由这个装置来完成一个密钥向另一个密钥的变换。
除了在保护装置里,即使在节点内也不会出现明文。
端对端方式由发送方加密的数据在没有到达最终目的地——接受节点之前不被解密。
加密、解密只是在源节点和目的节点进行。
概念:简述对称密码算法和公钥密码算法的区别简述对称密码算法和公钥密码算法的区别
(1)在对称密钥体制中,它的加密密钥和解密密钥的密码体制是相同的,
收发⽅共享密钥(即⼀个密钥)
对称密码的密钥是保密的,没有密钥,解密就不可能。
知道算法和若⼲密⽂不⾜以确定密钥。
(2)公钥密码体制中,使⽤不同的加密密钥和解密密钥,
并且加密密钥是公开的,解密密钥是保密的,
发送⽅拥有加密密钥或者解密密钥,⽽接受⽅拥有另⼀个密钥
(相对⽽要,其实接发⽅都有两个密钥,⾃⼰的加密密钥,以及对⽅分享的解密密钥)
两个密钥之⼀是保密的,⽆解密密钥,解密不可⾏。
知道算法和其中⼀个密钥以及若⼲的秘闻不能确定另⼀个密钥。
云南大学数学与统计学实验教学中心实验报告一、实验目的:通过实验掌握AES加密实验的构造算法,以及其重要思想。
二、实验内容:查阅资料,实现AES密码体制的编码算法、译码算法、子密钥生成算法三、实验环境Win7、Eclipse四、实验过程(请学生认真填写):实验过程、结果以及相应的解释:1. 预备知识密码学中的高级加密标准(Advanced Encryption Standard,AES),是一种对称加密的方法。
本实验使用Java平台来编写的,虽然在java中已经很好的实现了AES等安全机制,但是为了了解如何实现,还是写了一个AES加密的java程序。
2. 实验过程A、原理分析:大多数AES计算是在一个特别的有限域完成的。
AES加密过程是在一个4×4的字节矩阵上运作,这个矩阵又称为“体(state)”,其初值就是一个明文区块(矩阵中一个元素大小就是明文区块中的一个Byte)。
(Rijndael加密法因支持更大的区块,其矩阵行数可视情况增加)加密时,各轮AES加密循环(除最后一轮外)均包含4个步骤:AddRoundKey —矩阵中的每一个字节都与该次回合金钥(round key)做XOR运算;每个子密钥由密钥生成方案产生。
SubBytes —通过一个非线性的替换函数,用查找表的方式把每个字节替换成对应的字节。
ShiftRows —将矩阵中的每个横列进行循环式移位。
MixColumns —为了充分混合矩阵中各个直行的操作。
这个步骤使用线性转换来混合每列的四个字节。
最后一个加密循环中省略MixColumns步骤,而以另一个AddRoundKey取代。
B、具体代码如下://如6.2,若是将每一行看做是一个对象的话//具体实现的整体结构思想如此下图结果如下://得到结果与真实结果一样。
说明正确具体代码如下:由于所写代码过多,所以,本代码附在最后!五、实验总结1.遇到的问题及分析:遇到问题:其实这次编写程序遇到的问题还是蛮多的!例如S盒子的生成、逆S盒子的生成,算法中的每一步轮转,密钥生成,密钥长度等都遇到了问题。
由于时间仓促,这里就不一一举出来了。
分析并解决:-通过图书馆查询相应资料以及课本查阅得到了一些解决。
同时在网上查找到了一使用C++编写的程序代码以及算法理论。
得到了解决。
2.体会和收获。
编程实现了AES,个人感觉AEs实现起来还是比较困难的(对于我来说)因为他中间的矩阵操作复杂。
当然收获就是能有一定能力来编写这样的一个程序了。
六、参考文献计算机网络课本。
七、教师评语:附录:AES代码*************************Aes.java***************************** package AES;/*** AES字节数组加密算法类*/public class Aes {private int Nb;// 以32位为单位的字长private int Nk;// 以32位为单位的密钥长度private int Nr;// 轮数private byte[] key;// 密钥private byte[][] Sbox;// S盒矩阵private byte[][] iSbox;// s盒逆矩阵private byte[][] w;// 密钥调度表private byte[][] Rcon;// 轮常数表private byte[][] State;// 状态矩阵/*** 构造方法* @param keySize* @param keyBytes*/public Aes(int keySize, byte[] keyBytes, int Nb) { SetNbNkNr(keySize, Nb);this.key = new byte[this.Nk * 4];this.key = keyBytes;BuildSbox();BuildInvSbox();BuildRcon();KeyExpansion();}/*** 生成Rcon轮常数矩阵*/private void BuildRcon() {this.Rcon = new byte[100][4];Rcon[0][0] = 0x00;// Rcon[1][0]=0x01;for (int i = 1; i < 100; i++) {Rcon[i][0] = gfmultby02(Rcon[i - 1][0]);}}/*** 设置Nb,Nk,Nr* @param keysize*/private void SetNbNkNr(int keysize, int Nb) { this.Nb = Nb;switch (keysize) {case KEYSIZE.Bit128:this.Nk = 4;this.Nr = 10;break;case KEYSIZE.Bit192:this.Nk = 6;this.Nr = 12;break;case KEYSIZE.Bit256:this.Nk = 8;this.Nr = 14;break;}}/*** 生成S盒矩阵*/private void BuildSbox() {this.Sbox = new byte[][] {/* 0 1 2 3 4 5 6 7 8 9 a b c d e f *//* 0 */{ 0x63, 0x7c, 0x77, 0x7b, (byte) 0xf2, 0x6b, 0x6f,(byte) 0xc5, 0x30, 0x01, 0x67, 0x2b, (byte) 0xfe,(byte) 0xd7, (byte) 0xab, 0x76 },/* 1 */{ (byte) 0xca, (byte) 0x82, (byte) 0xc9, 0x7d,(byte) 0xfa, 0x59, 0x47, (byte) 0xf0, (byte) 0xad,(byte) 0xd4, (byte) 0xa2, (byte) 0xaf, (byte) 0x9c,(byte) 0xa4, 0x72, (byte) 0xc0 },/* 2 */{ (byte) 0xb7, (byte) 0xfd, (byte) 0x93, 0x26, 0x36,0x3f, (byte) 0xf7, (byte) 0xcc, 0x34, (byte) 0xa5,(byte) 0xe5, (byte) 0xf1, 0x71, (byte) 0xd8, 0x31, 0x15 }, /* 3 */{ 0x04, (byte) 0xc7, 0x23, (byte) 0xc3, 0x18,(byte) 0x96, 0x05, (byte) 0x9a, 0x07, 0x12,(byte) 0x80, (byte) 0xe2, (byte) 0xeb, 0x27,(byte) 0xb2, 0x75 },/* 4 */{ 0x09, (byte) 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a,(byte) 0xa0, 0x52, 0x3b, (byte) 0xd6, (byte) 0xb3,0x29, (byte) 0xe3, 0x2f, (byte) 0x84 },/* 5 */{ 0x53, (byte) 0xd1, 0x00, (byte) 0xed, 0x20,(byte) 0xfc, (byte) 0xb1, 0x5b, 0x6a, (byte) 0xcb,(byte) 0xbe, 0x39, 0x4a, 0x4c, 0x58, (byte) 0xcf }, /* 6 */{ (byte) 0xd0, (byte) 0xef, (byte) 0xaa, (byte) 0xfb,0x43, 0x4d, 0x33, (byte) 0x85, 0x45, (byte) 0xf9, 0x02,0x7f, 0x50, 0x3c, (byte) 0x9f, (byte) 0xa8 },/* 7 */{ 0x51, (byte) 0xa3, 0x40, (byte) 0x8f, (byte) 0x92,(byte) 0x9d, 0x38, (byte) 0xf5, (byte) 0xbc,(byte) 0xb6, (byte) 0xda, 0x21, 0x10, (byte) 0xff,(byte) 0xf3, (byte) 0xd2 },/* 8 */{ (byte) 0xcd, 0x0c, 0x13, (byte) 0xec, 0x5f,(byte) 0x97, 0x44, 0x17, (byte) 0xc4, (byte) 0xa7,0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 },/* 9 */{ 0x60, (byte) 0x81, 0x4f, (byte) 0xdc, 0x22, 0x2a,(byte) 0x90, (byte) 0x88, 0x46, (byte) 0xee,(byte) 0xb8, 0x14, (byte) 0xde, 0x5e, 0x0b, (byte) 0xdb }, /* a */{ (byte) 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,(byte) 0xc2, (byte) 0xd3, (byte) 0xac, 0x62,(byte) 0x91, (byte) 0x95, (byte) 0xe4, 0x79 },/* b */{ (byte) 0xe7, (byte) 0xc8, 0x37, 0x6d, (byte) 0x8d,(byte) 0xd5, 0x4e, (byte) 0xa9, 0x6c, 0x56,(byte) 0xf4, (byte) 0xea, 0x65, 0x7a, (byte) 0xae, 0x08 }, /* c */{ (byte) 0xba, 0x78, 0x25, 0x2e, 0x1c, (byte) 0xa6,(byte) 0xb4, (byte) 0xc6, (byte) 0xe8, (byte) 0xdd,0x74, 0x1f, 0x4b, (byte) 0xbd, (byte) 0x8b, (byte) 0x8a }, /* d */{ 0x70, 0x3e, (byte) 0xb5, 0x66, 0x48, 0x03,(byte) 0xf6, 0x0e, 0x61, 0x35, 0x57, (byte) 0xb9,(byte) 0x86, (byte) 0xc1, 0x1d, (byte) 0x9e },/* e */{ (byte) 0xe1, (byte) 0xf8, (byte) 0x98, 0x11, 0x69,(byte) 0xd9, (byte) 0x8e, (byte) 0x94, (byte) 0x9b,0x1e, (byte) 0x87, (byte) 0xe9, (byte) 0xce, 0x55,0x28, (byte) 0xdf },/* f */{ (byte) 0x8c, (byte) 0xa1, (byte) 0x89, 0x0d,(byte) 0xbf, (byte) 0xe6, 0x42, 0x68, 0x41,(byte) 0x99, 0x2d, 0x0f, (byte) 0xb0, 0x54,(byte) 0xbb, 0x16 } };}/*** 生成逆s盒矩阵*/private void BuildInvSbox() {int x, y;this.iSbox = new byte[16][16];for (int i = 0; i < 16; i++) {for (int j = 0; j < 16; j++) {x = (int) ((this.Sbox[i][j] >> 4) & 0x0f);y = (int) (this.Sbox[i][j] & 0x0f);this.iSbox[x][y] = (byte) (16 * i + j);}}}/*** 扩展密钥*/private void KeyExpansion() {this.w = new byte[Nb * (Nr + 1)][4];for (int row = 0; row < Nk; ++row) {this.w[row][0] = this.key[4 * row];this.w[row][1] = this.key[4 * row + 1];this.w[row][2] = this.key[4 * row + 2];this.w[row][3] = this.key[4 * row + 3];}byte[] temp = new byte[Nb];for (int row = Nk; row < Nb * (Nr + 1); ++row) {temp[0] = this.w[row - 1][0];temp[1] = this.w[row - 1][1];temp[2] = this.w[row - 1][2];temp[3] = this.w[row - 1][3];if (row % Nk == 0) {temp = SubWord(RotWord(temp));temp[0] = (byte) (temp[0] ^ this.Rcon[row / Nk][0]);temp[1] = (byte) (temp[1] ^ this.Rcon[row / Nk][1]);temp[2] = (byte) (temp[2] ^ this.Rcon[row / Nk][2]);temp[3] = (byte) (temp[3] ^ this.Rcon[row / Nk][3]);} else if (Nk > 6 && (row % Nk == 4)) {temp = SubWord(temp);}this.w[row][0] = (byte) (this.w[row - Nk][0] ^ temp[0]);this.w[row][1] = (byte) (this.w[row - Nk][1] ^ temp[1]);this.w[row][2] = (byte) (this.w[row - Nk][2] ^ temp[2]);this.w[row][3] = (byte) (this.w[row - Nk][3] ^ temp[3]);}}/*** SubWord方法* @param subWord* @return*/private byte[] SubWord(byte[] subWord) {for (int c = 0; c < subWord.length; ++c) {subWord[c] = this.Sbox[(subWord[c] >> 4) & 0x0f][(subWord[c] & 0x0f)];}return subWord;}/*** RotWord方法* @param rotWord* @return*/private byte[] RotWord(byte[] rotWord) {byte[] temp = rotWord;byte[] b = new byte[4];for (int i = 0; i < 4; i++) {b[i] = temp[(i + 1) % 4];}return b;}/*** 轮密钥加* @param round*/private void AddRoundKey(int round) {for (int r = 0; r < 4; ++r) {for (int c = 0; c < Nb; ++c) {this.State[r][c] = (byte) (this.State[r][c] ^ w[(round * Nb)+ c][r]);}}}/*** SubBytes方法*/private void SubBytes() {for (int r = 0; r < 4; ++r) {for (int c = 0; c < Nb; ++c) {this.State[r][c] = this.Sbox[(this.State[r][c] >> 4) &0x0f][(this.State[r][c] & 0x0f)];}}}/*** InvSubBytes方法*/private void InvSubBytes() {for (int r = 0; r < 4; ++r) {for (int c = 0; c < Nb; ++c) {this.State[r][c] = this.iSbox[(this.State[r][c] >> 4) &0x0f][(this.State[r][c] & 0x0f)];}}}/*** 行移位*/private void ShiftRows() {byte[][] temp = new byte[4][Nb];for (int r = 0; r < 4; ++r) {for (int c = 0; c < Nb; ++c) {temp[r][c] = this.State[r][c];}}for (int r = 1; r < 4; ++r) {for (int c = 0; c < Nb; ++c) {this.State[r][c] = temp[r][(c + r) % Nb];}}}/*** 逆行移位*/private void InvShiftRows() {byte[][] temp = new byte[4][Nb];for (int r = 0; r < 4; ++r) {for (int c = 0; c < Nb; ++c) {temp[r][c] = this.State[r][c];}}for (int r = 1; r < 4; ++r) {for (int c = 0; c < Nb; ++c) {this.State[r][c] = temp[r][(c - r + Nb) % Nb];}}}/*** 列混合*/private void MixColumns() {byte[][] temp = new byte[4][Nb];for (int r = 0; r < 4; ++r) {for (int c = 0; c < Nb; ++c) {temp[r][c] = this.State[r][c];}}for (int c = 0; c < Nb; ++c) {this.State[0][c] = (byte) (gfmultby02(temp[0][c])^ gfmultby03(temp[1][c]) ^ gfmultby01(temp[2][c]) ^gfmultby01(temp[3][c]));this.State[1][c] = (byte) (gfmultby01(temp[0][c])^ gfmultby02(temp[1][c]) ^ gfmultby03(temp[2][c]) ^gfmultby01(temp[3][c]));this.State[2][c] = (byte) (gfmultby01(temp[0][c]) ^ (gfmultby01(temp[1][c]) ^ gfmultby02(temp[2][c]) ^ gfmultby03(temp[3][c])));this.State[3][c] = (byte) (gfmultby03(temp[0][c])^ gfmultby01(temp[1][c]) ^ (gfmultby01(temp[2][c]) ^gfmultby02(temp[3][c])));}}/*** 逆列混合*/private void InvMixColumns() {byte[][] temp = new byte[4][Nb];for (int r = 0; r < 4; ++r) {for (int c = 0; c < Nb; ++c) {temp[r][c] = this.State[r][c];}}for (int c = 0; c < Nb; c++) {this.State[0][c] = (byte) (gfmultby0e(temp[0][c])^ gfmultby0b(temp[1][c]) ^ gfmultby0d(temp[2][c]) ^gfmultby09(temp[3][c]));this.State[1][c] = (byte) (gfmultby09(temp[0][c])^ gfmultby0e(temp[1][c]) ^ gfmultby0b(temp[2][c]) ^gfmultby0d(temp[3][c]));this.State[2][c] = (byte) (gfmultby0d(temp[0][c]) ^ (gfmultby09(temp[1][c]) ^ gfmultby0e(temp[2][c]) ^ gfmultby0b(temp[3][c])));this.State[3][c] = (byte) (gfmultby0b(temp[0][c])^ gfmultby0d(temp[1][c]) ^ (gfmultby09(temp[2][c]) ^gfmultby0e(temp[3][c])));}}// 有限域GF(28)部分变换private byte gfmultby01(byte b) {return b;}private byte gfmultby02(byte b) {if (((b >> 7) & 0x01) == 0) // !!!!!!!这里比较大小的时候注意符号位return (byte) (b << 1);elsereturn (byte) ((b << 1) ^ (byte) 0x1b);}private byte gfmultby03(byte b) {return (byte) (gfmultby02(b) ^ gfmultby01(b));}private byte gfmultby09(byte b) {return (byte) (gfmultby02(gfmultby02(gfmultby02(b))) ^ gfmultby01(b));}private byte gfmultby0b(byte b) {return (byte) (gfmultby02(gfmultby02(gfmultby02(b))) ^ gfmultby02(b) ^gfmultby01(b));}private byte gfmultby0d(byte b) {return (byte) (gfmultby02(gfmultby02(gfmultby02(b)))^ gfmultby02(gfmultby02(b)) ^ gfmultby01(b));}private byte gfmultby0e(byte b) {return (byte) (gfmultby02(gfmultby02(gfmultby02(b)))^ gfmultby02(gfmultby02(b)) ^ gfmultby02(b));}/*** 加密过程* @param input* @param output*/public void Cipher(byte[] input, byte[] output) {this.State = new byte[4][Nb];for (int i = 0; i < (4 * Nb); i++) {this.State[i / Nb][i % Nb] = input[i];}// 初始化状态矩阵AddRoundKey(0);// 轮密钥加for (int round = 1; round < Nr; ++round) {SubBytes();// S盒变换ShiftRows();// 行移位MixColumns();// 列混合AddRoundKey(round);}SubBytes();// S盒置换ShiftRows();// 行移位AddRoundKey(Nr);// 轮密钥加for (int i = 0; i < (4 * Nb); i++) {output[i] = this.State[i / Nb][i % Nb];}}/*** 解密过程* @param inputs* @param output*/public void Invcipher(byte[] input, byte[] output) {this.State = new byte[4][Nb];for (int i = 0; i < (4 * Nb); ++i) {this.State[i / Nb][i % Nb] = input[i];}// 初始化状态矩阵AddRoundKey(Nr);// 轮密钥加for (int round = Nr - 1; round > 0; round--) {InvShiftRows();// 逆行移位InvSubBytes();// 逆S盒置换AddRoundKey(round);// 轮密钥加InvMixColumns();// 逆列混合}InvShiftRows();// 逆行移位InvSubBytes();// 逆S盒置换AddRoundKey(0);// 轮密钥加for (int i = 0; i < (4 * Nb); ++i) {output[i] = this.State[i / Nb][i % Nb];}// 输出结果}}*************************AesCipherAndInvCipher.java**************** package AES;import java.io.UnsupportedEncodingException;import java.security.InvalidKeyException;/*** 辅助类处理明文字符输入字节数不匹配等问题*/public class AesCipherAndInvCipher {byte[] key;// 密钥private byte[] pt;// 明文字节数组private byte[] ct;private int mode;private int Nb = 0;private int dataLength;private int blockSize = 4;// 分组大小32位,4bytespublic AesCipherAndInvCipher(byte[] kb) {this.key = kb;}/*** 加密* @param kb* @param plainText* @return加密后密文字节数组*/private byte[] Eecrypt(String plainText, byte[] kb)throws InvalidKeyException {try {pt = plainText.getBytes("UTF-8");// 获取明文字节数组} catch (UnsupportedEncodingException e) {System.out.println("不支持的编码类型!");e.printStackTrace();}dataLength = pt.length;mode = dataLength % blockSize;// 判断明文数组长度是否与分组长度匹配ct = new byte[mode == 0 ? pt.length : dataLength / blockSize * 4 + 32];// 密文字节数组Nb = dataLength / blockSize;Aes a1 = new Aes(KEYSIZE.Bit128, kb, Nb);Aes a2 = new Aes(KEYSIZE.Bit128, kb, 4);Aes a3 = new Aes(KEYSIZE.Bit128, kb, 4);if (mode == 0) {a1.Cipher(pt, ct);} else {byte[] b1 = new byte[blockSize * Nb];// 匹配的部分byte[] b2 = new byte[16];// 剩余部分byte[] b3 = new byte[16];// 存明文长度byte[] c1 = new byte[b1.length];byte[] c2 = new byte[b2.length];byte[] c3 = new byte[b3.length];System.arraycopy(pt, 0, b1, 0, b1.length);System.arraycopy(pt, Nb * blockSize, b2, 0, mode);b3 = intToByteArray(dataLength);a1.Cipher(b1, c1);a2.Cipher(b2, c2);a3.Cipher(b3, c3);System.arraycopy(c1, 0, ct, 0, c1.length);System.arraycopy(c2, 0, ct, b1.length, c2.length);System.arraycopy(c3, 0, ct, b1.length + b2.length, c3.length);}return ct;}public byte[] EecryptToBytes(String plainText, byte[] kb)throws InvalidKeyException {byte[] ct = Eecrypt(plainText, kb);return ct;}public String EecryptToString(String plainText, byte[] kb)throws InvalidKeyException {byte[] ct = Eecrypt(plainText, kb);return BytesToString(ct);}/*** 解密*/public String Decrypt(byte[] ct, byte[] kb) {String s = "";if (mode == 0) {byte[] output = new byte[dataLength];Aes a = new Aes(KEYSIZE.Bit128, kb, Nb);a.Invcipher(ct, output);try {s = new String(output, "UTF-8");System.out.println("解密:" + s);} catch (UnsupportedEncodingException e) {System.out.println("不支持的编码格式!");e.printStackTrace();}} else {byte[] length = new byte[16];byte[] plainText1 = new byte[ct.length - 32];byte[] plainText2 = new byte[16];Aes a1 = new Aes(KEYSIZE.Bit128, kb, Nb);Aes a2 = new Aes(KEYSIZE.Bit128, kb, 4);Aes a3 = new Aes(KEYSIZE.Bit128, kb, 4);byte[] c1 = new byte[ct.length - 32];byte[] c2 = new byte[16];byte[] c3 = new byte[16];System.arraycopy(ct, ct.length - 16, c3, 0, c3.length);System.arraycopy(ct, ct.length - 32, c2, 0, c2.length);System.arraycopy(ct, 0, c1, 0, Nb * blockSize);a3.Invcipher(c3, length);// 解密明文字节数组长度a2.Invcipher(c2, plainText2);// 解密剩余的部分a1.Invcipher(c1, plainText1);// 解密匹配的部分int length1 = byteArrayToInt(length);byte[] output = new byte[length1];System.arraycopy(plainText1, 0, output, 0, plainText1.length);System.arraycopy(plainText2, 0, output, plainText1.length, length1 - plainText1.length);try {s = new String(output, "UTF-8");System.out.println("解密后明文:" + s);} catch (UnsupportedEncodingException e) {System.out.println("不支持的编码格式!");e.printStackTrace();}}return s;}public String Decrypt(String cryptText, byte[] kb) {byte[] ct = StringToBytes(cryptText);return Decrypt(ct, kb);}public String Decrypt(Byte[] ct, byte[] kb) {return Decrypt(ct, kb);}/*** int转化为Byte数组** @param value* @return*/private static byte[] intToByteArray(int value) {byte[] b = new byte[16];for (int i = 0; i < 4; i++) {int offset = (b.length - 1 - i) * 8;b[i] = (byte) ((value >>> offset) & 0xFF);}for (int i = 4; i < 16; i++) {b[i] = 0;}return b;}/*** byte数组转化为int** @param b* @return*/private static final int byteArrayToInt(byte[] b) {byte[] b1 = new byte[4];System.arraycopy(b, 0, b1, 0, 4);return (b1[0] << 24) + ((b1[1] & 0xFF) << 16) + ((b1[2] & 0xFF) << 8) + (b1[3] & 0xFF);}/*** 显示字节数组** @param b*/public static void DisplayAsBytes(byte[] b) {for (int i = 0; i < b.length; i++) {String hex = Integer.toHexString(b[i] & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}System.out.print(hex.toUpperCase() + " ");}System.out.println();}private static String BytesToString(byte[] b) {String s = "";for (int i = 0; i < b.length; i++) {String hex = Integer.toHexString(b[i] & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}s += hex;}return s;}private static byte[] StringToBytes(String cryptText) { byte[] b = new byte[cryptText.length() / 2];int[] a = new int[cryptText.length()];for (int i = 0; i < cryptText.length(); ++i) {String s = cryptText.substring(i, i + 1);if (s.equals("a"))a[i] = 10;else if (s.equals("b"))a[i] = 11;else if (s.equals("c"))a[i] = 12;else if (s.equals("d"))a[i] = 13;else if (s.equals("e"))a[i] = 14;else if (s.equals("f"))a[i] = 15;elsea[i] = Integer.valueOf(s);}for (int i = 0; i < cryptText.length() / 2; i++) {b[i] = (byte) (a[2 * i] * 16 + a[2 * i + 1]);}return b;}}*************************generateKey.java********************** package AES;import java.io.UnsupportedEncodingException;import java.security.InvalidKeyException;import java.util.Random;public class generateKey {private static byte[] key;/*** 随机生成key* @param keySize* @return* @throws InvalidKeyException*/public static byte[] generateRandomKey(int keySize)throws InvalidKeyException {if (keySize == KEYSIZE.Bit128 | keySize == KEYSIZE.Bit192| keySize == KEYSIZE.Bit256) {key = new byte[keySize / 8];for (int i = 0; i < keySize / 8; i++) {Random r = new Random();int tempByte = r.nextInt() * 255;key[i] = (byte) tempByte;}return key;} else {throw new InvalidKeyException("密钥长度错误,正确长度为128,192或者256位!");}}/*** 根据字符串生成key* @param keyStr* @return*/public static byte[] generateKeyFromString(String keyStr) {byte[] tempkey = null;try {tempkey = keyStr.getBytes("UTF-8");} catch (UnsupportedEncodingException e) {System.out.println("不支持的编码类型!");e.printStackTrace();}if (tempkey.length < 128) {key = new byte[16];byte lastByte = tempkey[tempkey.length - 1];for (int i = tempkey.length; i < 16; i++) {key[i] = gfmultby02(lastByte);lastByte = key[i - 1];}} else if (tempkey.length > 128 && tempkey.length < 192) {key = new byte[24];byte lastByte = tempkey[tempkey.length - 1];for (int i = tempkey.length; i < 24; i++) {key[i] = gfmultby02(lastByte);lastByte = key[i - 1];}} else if (tempkey.length > 192 && tempkey.length < 256) {key = new byte[32];byte lastByte = tempkey[tempkey.length - 1];for (int i = tempkey.length; i < 32; i++) {key[i] = gfmultby02(lastByte);lastByte = key[i - 1];}} else if (tempkey.length > 256) {key = new byte[32];System.arraycopy(tempkey, 0, key, 0, 32);} else {key = tempkey;}return key;}public int getKeyLength() {return key.length;}private static byte gfmultby02(byte b) {if (((b >> 7) & 0x01) == 0) // !!!!!!!这里比较大小的时候注意符号位return (byte) (b << 1);elsereturn (byte) ((b << 1) ^ (byte) 0x1b);// 消除符号位可以用b&0xff}}*************************KEYSIZE.java*************************package AES;/*** 密钥长度** @author卢富毓*/public class KEYSIZE {public static final int Bit128 = 128;// 128位public static final int Bit192 = 192;// 192位public static final int Bit256 = 256;// 256位}*************************testAes.java*************************package AES;import java.security.InvalidKeyException;public class testAes {public static void main(String[] args) {byte[] plainText = new byte[] { 0x11, 0x11, 0x22, 0x33, 0x44, 0x55,0x66, 0x77, (byte) 0x88, (byte) 0x99, (byte) 0xaa, (byte) 0xbb,(byte) 0xcc, (byte) 0xdd, (byte) 0xee, (byte) 0xff, 0x00, 0x11,// 0x22,// 0x33,0x44,// 0x55,0x66, 0x77 };// 明文byte[] cipherText = new byte[20];byte[] decipheredText = new byte[20];byte[] keyBytes = null;try {keyBytes = generateKey.generateKeyFromString("AES1wrwe2432v112wwwwwwwwwwwwwwwwwwww@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@wwwwwwwwwwwwwwwwwwwwwww34@#%$1234fffffffffffffffffffffff");} catch (Exception e1) {// TODO Auto-generated catch blocke1.printStackTrace();}Aes a = new Aes(KEYSIZE.Bit192, keyBytes, 5);System.out.println("***********************测试1****************************");byte[] key1 = null;try {key1 = generateKey.generateRandomKey(KEYSIZE.Bit128);} catch (InvalidKeyException e1) {e1.printStackTrace();}AesCipherAndInvCipher aes = new AesCipherAndInvCipher(key1);byte[] dt = null;String ss = null;try {dt = new byte[16];dt = aes.EecryptToBytes("AES11212121212121", keyBytes);ss = aes.EecryptToString("AES1wrwe2432v1343", keyBytes);System.out.println("明文1:AES11212121212121");System.out.println("明文2:AES1wrwe2432v1343");System.out.println("字节式加密,密文:" + new String(dt));System.out.println("字符串式加密,密文:" + ss);} catch (InvalidKeyException e) {e.printStackTrace();}aes.Decrypt(dt, keyBytes);aes.Decrypt(ss, keyBytes);System.out.println("\n*************************测试2*****************************");AesCipherAndInvCipher aes1 = new AesCipherAndInvCipher(key1);byte[] dt1 = null;try {// dt = new byte[16];String plainText1 = "uuid=FSFASW24S-0342-FEW3-3F33-F44F2SE523432D";dt1 = aes1.EecryptToBytes(plainText1, keyBytes);System.out.println("明文:" + plainText1);System.out.println("字节式加密,密文:" + new String(dt1));} catch (InvalidKeyException e) {e.printStackTrace();}aes1.Decrypt(dt1, keyBytes);}/*** 显示16进制* @param b*/public static void DisplayAsBytes(byte[] b) {for (int i = 0; i < b.length; i++) {String hex = Integer.toHexString(b[i] & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}System.out.print(hex.toUpperCase() + " ");}System.out.println();}}。