AES加密解密与代码实现详解
JAVA实现AES的加密和解密算法

JAVA实现AES的加密和解密算法AES(高级加密标准)是一种对称加密算法,可以通过Java的javax.crypto库来实现。
下面我们将介绍一种基于Java的AES加密和解密算法的实现方法。
1.导入所需的包在Java中使用AES加密和解密算法需要导入以下两个包:```import javax.crypto.Cipher;import javax.crypto.spec.SecretKeySpec;```2.创建加密和解密函数首先,我们需要创建加密函数和解密函数。
加密函数将输入的明文数据加密为密文,解密函数将输入的密文数据解密为明文。
```javaprivate static byte[] encrypt(byte[] key, byte[] data) throws ExceptionSecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);return cipher.doFinal(data);private static byte[] decrypt(byte[] key, byte[] encryptedData) throws ExceptionSecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);return cipher.doFinal(encryptedData);```3.测试加密和解密函数为了验证加密和解密函数的正确性,我们可以创建一个测试函数来测试它们。
AES算法C语言讲解与实现

AES算法C语言讲解与实现AES(Advanced Encryption Standard)是一种对称加密算法,被广泛应用于各种应用中,如保护通信、数据安全等。
AES算法采用分组密码的方式,将明文数据分成若干个大小相等的分组,然后对每个分组进行加密操作。
1. 密钥扩展(Key Expansion):AES算法中使用的密钥长度分为128位、192位和256位三种,密钥长度不同,密钥扩展的轮数也不同。
根据密钥长度,需要扩展成多少个轮密钥。
扩展过程中需要进行字节代换、循环左移、模2乘法等操作。
2. 子密钥生成(Subkey Generation):根据密钥扩展的结果,生成每一轮需要使用的子密钥。
3. 字节替换(SubBytes):将每个字节替换为S盒中对应的值。
S盒是一个固定的预先计算好的查找表。
4. 行移位(ShiftRows):对矩阵的行进行循环左移,左移的位数根据行数而定。
5. 列混合(MixColumns):将每列的四个字节进行混合。
混合操作包括乘法和异或运算。
6. 轮密钥加(AddRoundKey):将每一轮得到的结果与轮密钥进行异或运算。
以上就是AES算法的六个步骤的实现过程,下面我们来具体讲解一下。
首先,我们需要定义一些辅助函数,如字节代换函数、循环左移函数等。
```cuint8_t substitution(uint8_t byte) return sBox[byte];void shiftRows(uint8_t *state)uint8_t temp;//第二行循环左移1位temp = state[1];state[1] = state[5];state[5] = state[9];state[9] = state[13];state[13] = temp;//第三行循环左移2位temp = state[2];state[2] = state[10];state[10] = temp;temp = state[6];state[6] = state[14];state[14] = temp;//第四行循环左移3位temp = state[15];state[15] = state[11];state[11] = state[7];state[7] = state[3];state[3] = temp;void mixColumns(uint8_t *state)int i;uint8_t temp[4];for(i = 0; i < 4; i++)temp[0] = xTime(state[i * 4]) ^ xTime(state[i * 4 + 1]) ^ state[i * 4 + 1] ^state[i * 4 + 2] ^ state[i * 4 + 3];temp[1] = state[i * 4] ^ xTime(state[i * 4 + 1]) ^xTime(state[i * 4 + 2]) ^state[i * 4 + 2] ^ state[i * 4 + 3];temp[2] = state[i * 4] ^ state[i * 4 + 1] ^ xTime(state[i * 4 + 2]) ^xTime(state[i * 4 + 3]) ^ state[i * 4 + 3];temp[3] = xTime(state[i * 4]) ^ state[i * 4] ^ state[i * 4 + 1] ^state[i * 4 + 2] ^ xTime(state[i * 4 + 3]);state[i * 4] = temp[0];state[i * 4 + 1] = temp[1];state[i * 4 + 2] = temp[2];state[i * 4 + 3] = temp[3];}```接下来,我们实现密钥扩展和子密钥生成的过程。
A E S 加 密 算 法 的 原 理 详 解 ( 2 0 2 0 )

# AES加密原理-详解0 AES简介美国国家标准技术研究所在2001年发布了高级加密标准(AES)。
AES 是一个对称分组密码算法,旨在取代DES成为广泛使用的标准。
根据使用的密码长度,AES最常见的有3种方案,用以适应不同的场景要求,分别是AES-128、AES-192和AES-256。
本文主要对AES-128进行介绍,另外两种的思路基本一样,只是轮数会适当增加。
1 算法流程AES加解密的流程图如下:AES加密过程涉及到4种操作:字节替代(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)和轮密钥加(AddRoundKey)。
解密过程分别为对应的逆操作。
由于每一步操作都是可逆的,按照相反的顺序进行解密即可恢复明文。
加解密中每轮的密钥分别由初始密钥扩展得到。
算法中16字节的明文、密文和轮密钥都以一个4x4的矩阵表示。
接下来分别对上述5种操作进行介绍。
1.1 字节代替下图(a)为S盒,图(b)为S-1(S盒的逆)S和S-1分别为16x16的矩阵。
假设输入字节的值为a=a7a6a5a4a3a2a1a0,则输出值为S[a7a6a5a4][a3a2a1a0],S-1的变换也同理。
例如:字节00替换后的值为(S[0][0]=)63,再通过S-1即可得到替换前的值,(S-1 [6][3]=)00。
1.2 行移位行移位的功能是实现一个4x4矩阵内部字节之间的置换。
1.2.1 正向行移位正向行移位的原理图如下:实际移位的操作即是:第一行保存不变,第二行循环左移1个字节,第三行循环左移2个字节,第四行循环左移3个字节。
假设矩阵的名字为state,用公式表示如下:state’[i][j] = state[i][(j+i)%4];其中i、j属于[0,3]1.2.2 逆向行移位逆向行移位即是相反的操作,用公式表示如下:state’[i][j] = state[i][(4+j-i)%4];其中i、j属于[0,3]1.3 列混淆列混淆:利用GF(28)域上算术特性的一个代替。
python实现aes加密解密

python实现aes加密解密引⼦: 在windows中python3使⽤ pycryptodemo 模块实现Aes加密解密。
Aes加密有多种⽅式,⾃⼰可以上⽹了解下。
AES是每16位⼀加密,并且保证key和vi都是16位的。
废话不多说直接上代码。
import base64from Crypto.Cipher import AESfrom binascii import b2a_hex,a2b_hexclass PrpCrypt(object):def __init__(self,key,iv):self.key=key.encode('utf-8')self.mode=AES.MODE_CBCself.iv=iv.encode('utf-8')def pad_byte(self, b):'''1 先计算所传⼊bytes类型⽂本与16的余数2 在将此余数转成bytes 当然⽤0补位也可以3 已知了余数那么就⽤余数*被转成的余数,就得到了需要补全的bytes4 拼接原有⽂本和补位:param b: bytes类型的⽂本:return: 返回补全后的bytes⽂本'''bytes_num_to_pad = AES.block_size - (len(b) % AES.block_size)# python3 中默认unicode转码# 实际上byte_to_pad 就已经将数字转成了unicode 对应的字符即使你的⼊参正好是16的倍数,那么bytes也是把列表整体的转码也是有值的# 后边解密的匿名函数拿到最后⼀个数字后,就知道应该截取的长度,在反着切⽚就⾏了# 这样保证了数据的完整性byte_to_pad = bytes([bytes_num_to_pad])padding = byte_to_pad * bytes_num_to_padpadded = b + paddingreturn paddeddef encrypt(self,text):'''1 先⽣成aes实例2 对传⼊的text转成bytes3 对传⼊的text补全4 调⽤encrypt 加密得到密⽂5 先将密⽂转16进制,在将16进制⽤base64转码,然后在将得到的base64解码其实在步骤4 就已经完成了aes加密,我所在的公司加密⽐较复杂,需要的可以直接返回步骤4的值:param text::return:'''cryptor = AES.new(self.key,self.mode,self.iv)text = text.encode('utf-8')text = self.pad_byte(text)self.ciphertext = cryptor.encrypt(text)cryptbase64 = base64.b64encode(b2a_hex(self.ciphertext)).decode('utf8')return cryptbase64def decrypt(self,text):'''解密和加密的顺序是相反的1 定义匿名函数,去掉补位2 base64解码3 ⽣成aes实例4 16进制转2进制5 使⽤decrypt解码得到补全的bytes类型明⽂:param text::return: 解密且去掉补位的明⽂'''unpad = lambda s: s[:-ord(s[len(s) - 1:])]base64Str = base64.b64decode(text.encode('utf8'))cryptor = AES.new(self.key, self.mode, self.iv)aesStr = cryptor.decrypt(a2b_hex(base64Str))aesStr = str(unpad(aesStr), encoding='utf8')return aesStrif __name__ == '__main__':data='sadfsasdgsdfgdsf123'pc=PrpCrypt('daajanbaqa654321','1234567890123456')redata = pc.encrypt(data)print(redata)result=pc.decrypt(redata)print(result) 思路: 这⾥引⽤⼀句前辈的话,思路很重要。
AES加密解密C语言实现

快毕业了,最后一个课程设计,《基于Windows Socket的安全通信》,内容就是基于AES加密的SOCKET通信,貌似挺简单,不过要用VC++6.0开发,C++我确实没有任何代码经验,虽然不是强制性,但由于机房里各种纠结,只能用它了(用Java没有挑战性,封装得太好了...也算熟悉下VC++吧)先搞定AES算法,基本变换包括SubBytes(字节替代)、ShiftRows(行移位)、MixColumns(列混淆)、AddRoundKey(轮密钥加)其算法一般描述为明文及密钥的组织排列方式(其中c i是6310即011000112的第i位),用矩阵表示为本来打算把求乘法逆和仿射变换算法敲上去,最后还是放弃了...直接打置换表行移位变换完成基于行的循环位移操作,变换方法:即行移位变换作用于行上,第0行不变,第1行循环左移1个字节,第2行循b(x) = (03·x + 01·x + 01·x + 02) ·a(x) mod(x + 1)矩阵表示形式:其中FFmul为有限域GF(28)上的乘法,标准算法应该是循环8次(b与a的每一位相乘,结果相加),但这里只用到最低2位,解密时用到的逆列混淆也只用了低4位,所以在这里高4位的运算是多余的,只计算低4位。
KeyExpansion(密钥扩展)将输入的密钥扩展为11组128位密钥组,其中第0组为输入密钥本身其后第n组第i列为第n-1组第i列与第n组第i-1列之和(模2加法,1 <= i <=3)对于每一组第一列即i=0,有特殊的处理将前一列即第n-1组第3列的4个字节循环左移1个字节,加密时默认参数length=0,为要加密的数据长度,如果使用默认值,则作为字符串处理,以'\0'为结尾计算长度加密时传进的指针要预留够16整数倍字节的空间,因为加密操作直接修改原数据,不足128位可能造成内存溢出。
Python中如何使用AES算法进行加密和解密

Python中如何使用AES算法进行加密和解密一、引言随着互联网的快速发展,财务交易、个人资料和敏感数据被传输在网络上的频率越来越高。
因此,保护数据的安全性和私密性成为了一项至关重要的任务。
加密技术是一种重要的手段,可以解决这个问题。
其中最受欢迎和应用广泛的加密算法是AES。
本文主要介绍Python中如何使用AES算法进行加密和解密的方法。
二、AES算法简介AES算法是高级加密标准(Advanced Encryption Standard)的缩写。
它是目前广泛使用的对称加密算法之一,是一种分组密码,加密和解密使用相同的秘钥(Key)进行。
AES算法的加密和解密都是基于密钥和明文的操作。
AES算法对明文进行加密时需要三个参数:明文、密钥和向量(IV),其中向量是用于增加随机性和异质性以增强密码体制的安全性的。
加密后,得到的密文只有通过使用相同的密钥和向量才能被解密。
因此,必须确保密钥和向量的安全性。
AES算法的强度与密钥长度有关,通常使用128、192或256位密钥。
三、Python中使用AES算法加密和解密的方法Python中使用AES算法加密和解密需要使用Crypto库,它是Python中专门提供密码学操作的库。
在使用之前,需要先安装Crypto 库:```pythonpip install pycrypto```在Crypto库中,有很多算法可以使用。
在这里,我们使用AES算法。
首先,需要导入Crypto库中的AES模块,如下所示:```pythonfrom Crypto.Cipher import AES```接下来,定义用于加密和解密的key和iv:```pythonkey = '0123456789abcdef'iv = 'fedcba9876543210'```key和iv都是以字符串形式定义的,长度分别为16个字符(128位)和16个字符(128位)。
AES加密C语言实现代码

AES加密C语言实现代码以下是一个简单的C语言实现AES加密算法的代码:```c#include <stdio.h>#include <stdlib.h>#include <stdint.h>//定义AES加密的轮数#define NR 10//定义AES加密的扩展密钥长度#define Nk 4//定义AES加密的行数和列数#define Nb 4//定义AES加密的状态矩阵typedef uint8_t state_t[4][4];//定义AES加密的S盒变换表static const uint8_t sbox[256] =//S盒变换表};//定义AES加密的轮常量表static const uint8_t Rcon[11] =//轮常量表};//定义AES加密的密钥扩展变换函数void KeyExpansion(const uint8_t* key, uint8_t* expandedKey) uint32_t* ek = (uint32_t*)expandedKey;uint32_t temp;//密钥拷贝到扩展密钥中for (int i = 0; i < Nk; i++)ek[i] = (key[4 * i] << 24) , (key[4 * i + 1] << 16) ,(key[4 * i + 2] << 8) , (key[4 * i + 3]);}//扩展密钥生成for (int i = Nk; i < Nb * (NR + 1); i++)temp = ek[i - 1];if (i % Nk == 0)//对上一个密钥的字节进行循环左移1位temp = (temp >> 8) , ((temp & 0xFF) << 24);//对每个字节进行S盒变换temp = (sbox[temp >> 24] << 24) , (sbox[(temp >> 16) & 0xFF] << 16) , (sbox[(temp >> 8) & 0xFF] << 8) , sbox[temp & 0xFF];// 取轮常量Rcontemp = temp ^ (Rcon[i / Nk - 1] << 24);} else if (Nk > 6 && i % Nk == 4)//对每个字节进行S盒变换temp = (sbox[temp >> 24] << 24) , (sbox[(temp >> 16) & 0xFF] << 16) , (sbox[(temp >> 8) & 0xFF] << 8) , sbox[temp & 0xFF];}//生成下一个密钥ek[i] = ek[i - Nk] ^ temp;}//定义AES加密的字节替换函数void SubBytes(state_t* state)for (int i = 0; i < 4; i++)for (int j = 0; j < 4; j++)(*state)[i][j] = sbox[(*state)[i][j]];}}//定义AES加密的行移位函数void ShiftRows(state_t* state) uint8_t temp;//第2行循环左移1位temp = (*state)[1][0];(*state)[1][0] = (*state)[1][1]; (*state)[1][1] = (*state)[1][2]; (*state)[1][2] = (*state)[1][3]; (*state)[1][3] = temp;//第3行循环左移2位temp = (*state)[2][0];(*state)[2][0] = (*state)[2][2]; (*state)[2][2] = temp;temp = (*state)[2][1];(*state)[2][1] = (*state)[2][3]; (*state)[2][3] = temp;//第4行循环左移3位temp = (*state)[3][0];(*state)[3][0] = (*state)[3][3];(*state)[3][3] = (*state)[3][2];(*state)[3][2] = (*state)[3][1];(*state)[3][1] = temp;//定义AES加密的列混淆函数void MixColumns(state_t* state)uint8_t temp, tmp, tm;for (int i = 0; i < 4; i++)tmp = (*state)[i][0];tm = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;temp = (*state)[i][0] ^ (*state)[i][1];(*state)[i][0] ^= temp ^ tm;temp = (*state)[i][1] ^ (*state)[i][2];(*state)[i][1] ^= temp ^ tm;temp = (*state)[i][2] ^ (*state)[i][3];(*state)[i][2] ^= temp ^ tm;temp = (*state)[i][3] ^ tmp;(*state)[i][3] ^= temp ^ tm;}//定义AES加密的轮密钥加函数void AddRoundKey(state_t* state, const uint8_t* roundKey) for (int i = 0; i < 4; i++)for (int j = 0; j < 4; j++)(*state)[j][i] ^= roundKey[i * 4 + j];}}//定义AES加密函数void AES_Encrypt(const uint8_t* plainText, const uint8_t* key, uint8_t* cipherText)state_t* state = (state_t*)cipherText;uint8_t expandedKey[4 * Nb * (NR + 1)];//密钥扩展KeyExpansion(key, expandedKey);//初始化状态矩阵for (int i = 0; i < 4; i++)for (int j = 0; j < 4; j++)(*state)[j][i] = plainText[i * 4 + j];}}//第1轮密钥加AddRoundKey(state, key);//迭代执行第2至第10轮加密for (int round = 1; round < NR; round++) SubBytes(state);ShiftRows(state);MixColumns(state);AddRoundKey(state, expandedKey + round * 16); }//执行第11轮加密SubBytes(state);ShiftRows(state);AddRoundKey(state, expandedKey + NR * 16);int maiuint8_t plainText[16] =//明文数据};uint8_t key[16] =//密钥数据};uint8_t cipherText[16];AES_Encrypt(plainText, key, cipherText);。
mysql_aes解密_填充方法_概述及解释说明

mysql aes解密填充方法概述及解释说明1. 引言1.1 概述本文将详细介绍MySQL中的AES解密方法及其填充方法。
随着信息安全的日益重视,对数据进行加密保护成为了不可或缺的一环。
AES(Advanced Encryption Standard)作为一种流行的对称加密算法,在数据库领域也得到了广泛应用。
MySQL作为最流行的关系型数据库管理系统之一,提供了内置函数和存储过程用于实现AES解密操作。
1.2 文章结构为了系统地介绍MySQL中的AES解密及其填充方法,本文将分为五个主要部分。
首先,引言部分将简述文章内容并概括本文结构。
其次,正文部分将首先对AES加密算法进行简单介绍,并重点阐述MySQL中的AES解密方法。
然后,将详细说明填充方法及其在MySQL中的应用。
接下来,将深入探讨AES解密过程的三个关键步骤,并逐步进行解释说明。
在第四部分中,通过给出操作实例和说明来进一步帮助读者理解如何使用MySQL内置函数以及自定义存储过程实现AES解密功能,并针对常见问题进行了注意事项和解答。
最后,在结论和总结部分,将总结已掌握的知识点,并对MySQL AES解密填充方法的理解和意义进行评价,同时对未来发展方向和可能改进的地方进行展望。
1.3 目的本文旨在帮助读者了解MySQL中的AES解密方法及其填充方法,并掌握如何使用相关函数和存储过程来实现AES解密操作。
通过对AES解密过程的详细解释和操作实例的演示,读者将能够深入理解AES解密的原理和应用,并能够灵活运用于实际项目中。
此外,本文还将介绍常见问题及其解答,以便读者更好地应对实际开发中可能遇到的挑战。
通过阅读本文,读者可以为数据库安全性提升做出贡献,保护重要数据免受未经授权访问和窃取的风险。
2. 正文:2.1 AES加密算法简介AES(Advanced Encryption Standard)是一种对称加密算法,是目前最常用的加密算法之一。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
先搞定AES算法,基本变换包括SubBytes(字节替代)、ShiftRows(行移位)、MixColumns(列混淆)、AddRoundKey(轮密钥加)
其算法一般描述为
明文及密钥的组织排列方式
ByteSubstitution(字节替代)
非线性的字节替代,单独处理每个字节:
求该字节在有限域GF(28)上的乘法逆,"0"被映射为自身,即对于α∈GF(28),求β∈GF(28),
使得α·β=β·α=1mod(x8+x4+x2+x+1)。
对上一步求得的乘法逆作仿射变换
y i=x i + x(i+4)mod8 + x(i+6)mod8 + x(i+7)mod8 + c i
(其中c i是6310即011000112的第i位),用矩阵表示为
本来打算把求乘法逆和仿射变换算法敲上去,最后还是放弃了...直接打置换表
下面是逆置换表,解密时使用
这里遇到问题了,本来用纯c初始化数组很正常,封装成类以后发现不能初始化,不管是声明、构造函数都无法初始化,百歌谷度了一通后没有任何答案,无奈只能在构造函数中声明一个局部变量数组并初始化,然后用memcpy,(成员变量名为Sbox/InvSbox,局部变量名sBox/invsBox)
ShiftRows(行移位变换)
行移位变换完成基于行的循环位移操作,变换方法:
即行移位变换作用于行上,第0行不变,第1行循环左移1个字节,第2行循环左移2个字节,第3行循环左移3个字节。
MixColumns(列混淆变换)
逐列混合,方法:
b(x) = (03·x3 + 01·x2 + 01·x + 02) · a(x) mod(x4 + 1)
其中FFmul为有限域GF(28)上的乘法,标准算法应该是循环8次(b与a的每一位相乘,结果相加),但这里只用到最低2位,解密时用到的逆列混淆也只用了低4位,所以在这里高4位的运算是多余的,只计算低4位。
AddRoundKey(轮密钥加变换)
简单来说就是逐字节相加,有限域GF(28)上的加法是模2加法,即异或
void AES::AddRoundKey(unsigned char state[][4], unsigned char k[][4])
{
int r,c;
for(c=0; c<4; c++)
{
for(r=0; r<4; r++)
{
state[r][c] ^= k[r][c];
}
}
}
KeyExpansion(密钥扩展)
将输入的密钥扩展为11组128位密钥组,其中第0组为输入密钥本身
其后第n组第i列为第n-1组第i列与第n组第i-1列之和(模2加法,1<= i <=3)
对于每一组第一列即i=0,有特殊的处理
将前一列即第n-1组第3列的4个字节循环左移1个字节,
并对每个字节进行字节替代变换SubBytes
将第一行(即第一个字节)与轮常量rc[n]相加
最后再与前一组该列相加
void AES::KeyExpansion(unsigned char* key, unsigned char w[][4][4])
{
int i,j,r,c;
unsigned char rc[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
for(r=0; r<4; r++)
{
for(c=0; c<4; c++)
{
w[0][r][c] = key[r+c*4];
}
}
for(i=1; i<=10; i++)
{
for(j=0; j<4; j++)
{
unsigned char t[4];
for(r=0; r<4; r++)
{
t[r] = j ? w[i][r][j-1] : w[i-1][r][3];
}
if(j == 0)
{
unsigned char temp = t[0];
for(r=0; r<3; r++)
{
t[r] = Sbox[t[(r+1)%4]];
}
t[3] = Sbox[temp];
t[0] ^= rc[i-1];
}
for(r=0; r<4; r++)
{
w[i][r][j] = w[i-1][r][j] ^ t[r];
}
}
}
}
解密的基本运算
AES解密算法与加密不同,基本运算中除了AddRoundKey(轮密钥加)不变外,其余的都需要进行逆变换,即
InvSubBytes(逆字节替代)、InvShiftRows(逆行移位)、InvMixColumns (逆列混淆)
加密过程
先将输入的明文按列序组合成4*4的矩阵,直接与第0组密钥(即输入的密钥)相加(异或),作为轮加密的输入
然后循环10次进行SubBytes、ShiftRows、MixColumns、AddRoundKey 运算,最后恢复原序列
需要注意的是最后一轮并不进行MixColumns(列混淆变换)
unsigned char* AES::Cipher(unsigned char* input)
{
unsigned char state[4][4];
int i,r,c;
for(r=0; r<4; r++){
for(c=0; c<4 ;c++) {
state[r][c] = input[c*4+r];
}
}
AddRoundKey(state,w[0]);
for(i=1; i<=10; i++){
SubBytes(state);
ShiftRows(state);
if(i!=10)MixColumns(state);
AddRoundKey(state,w[i]);
}
for(r=0; r<4; r++) {
for(c=0; c<4 ;c++){
input[c*4+r] = state[r][c];
}
}
return input;
}
解密过程
unsigned char* AES::InvCipher(unsigned char* input) {
unsigned char state[4][4];
int i,r,c;
for(r=0; r<4; r++)
{
for(c=0; c<4 ;c++)
{
state[r][c] = input[c*4+r];
}
}
AddRoundKey(state, w[10]);
for(i=9; i>=0; i--)
{
InvShiftRows(state);
InvSubBytes(state);
AddRoundKey(state, w[i]);
if(i)InvMixColumns(state);
}
for(r=0; r<4; r++)
{
for(c=0; c<4 ;c++)
{
input[c*4+r] = state[r][c];
}
}
return input;
}
对外部数据的加密/解密
至此已经实现了AES加密与解密的原型,在使用的时候一般处理的是字符串等,而不是直接传入128位的数据,所以要封装一下对外部数据的加解密处理
void* AES::Cipher(void* input, int length)
{
unsigned char* in = (unsigned char*) input;
int i;
if(!length) {
while(*(in+length++));
in = (unsigned char*) input;
}
for(i=0; i<length; i+=16){
Cipher(in+i);
}
return input;
}
void* AES::InvCipher(void* input, int length){
unsigned char* in = (unsigned char*) input;
int i;
for(i=0; i<length; i+=16){
InvCipher(in+i);
}
return input;
}
加密时默认参数length=0,为要加密的数据长度,如果使用默认值,则作为字符串处理,以'\0'为结尾计算长度
加密时传进的指针要预留够16整数倍字节的空间,因为加密操作直接修改原数据,不足128位可能造成内存溢出。