AES加密解密C语言实现
- 格式:docx
- 大小:250.36 KB
- 文档页数:13
成都信息工程学院课程设计报告AES加密解密软件的实现课程名称:应用密码算法程序设计学生姓名:樊培学生学号:2010121058专业班级:信息对抗技术101任课教师:陈俊2012 年6月7日课程设计成绩评价表目录1、选题背景 (4)2、设计的目标 (4)2.1基本目标: (4)2.2较高目标: (5)3、功能需求分析 (5)4、模块划分 (6)4.1、密钥调度 (6)4.2、加密 (8)4.2.1、字节代替(SubBytes) (8)4.2.2、行移位(ShiftRows) (10)4.2.3、列混合(MixColumn) (11)4.2.4、轮密钥加(AddRoundKey) (13)4.2.5、加密主函数 (14)4.3、解密 (16)4.3.1、逆字节替代(InvSubBytes) (16)4.3.2、逆行移位(InvShiftRows) (17)4.3.3、逆列混合(InvMixCloumns) (17)4.3.4、轮密钥加(AddRoundKey) (18)4.3.5、解密主函数 (18)5.测试报告 (20)5.1主界面 (20)5.2测试键盘输入明文和密钥加密 (20)5.3测试键盘输入密文和密钥加密 (21)5.3测试文件输入明文和密钥加密 (22)5.4测试文件输入密文和密钥加密 (22)5.5软件说明 (23)6.课程设计报告总结 (23)7.参考文献 (24)1、选题背景高级加密标准(Advanced Encryption Standard,AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。
这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。
经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。
2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。
aes加密算法的输入c语言实例1.引言1.1 概述概述部分应该对文章的主题进行一个简要介绍,提供一些背景信息和基本概念,以帮助读者了解接下来要讨论的内容。
下面是一个示例:在当今信息安全领域,数据的加密和保护是至关重要的。
随着互联网的发展和应用的广泛,如何确保用户的机密信息在传输和存储过程中不被未经授权的人访问和窃取,成为了一个极具挑战性的问题。
为了应对这个问题,许多加密算法被开发和广泛应用,其中AES(Advanced Encryption Standard,高级加密标准)算法就是其中之一。
AES算法是一种对称加密算法,它可以对数据进行高强度的加密和解密,以保护数据的机密性。
它是目前最常用和最可靠的加密算法之一,被广泛应用于各种安全通信和数据存储场景。
AES算法采用了分组加密和替代-置换网络结构,通过多轮的迭代运算和密钥扩展过程,将输入的明文数据转换为密文数据。
解密过程与加密过程相反,通过逆向的操作将密文数据恢复为明文数据。
本文的主要目的是介绍如何使用C语言来实现AES加密算法。
在接下来的内容中,我们将首先简要介绍AES算法的基本原理和步骤,然后详细讲解如何使用C语言来实现这些步骤。
通过本文的学习,读者将可以了解AES算法的基本运作原理,并掌握使用C语言编写AES加密算法的技巧。
在下一节中,我们将开始介绍AES加密算法的基本原理和步骤。
1.2 文章结构文章结构部分将对本文的组织结构和各章节内容进行介绍。
本文分为以下几个部分:1. 引言:本部分包括概述、文章结构和目的三个小节。
在概述中,将简要介绍AES加密算法和其在信息安全领域的重要性。
文章结构部分将重点介绍本文的整体组织架构和各章节内容的概括。
目的部分将明确本文的主要目标和意义。
2. 正文:本部分包括AES加密算法简介和C语言实现AES算法的基本步骤两个小节。
在AES加密算法简介中,将对AES算法的基本原理进行阐述,包括密钥长度、分组长度、轮数等方面的内容。
C#实现AES加密--解密///<summary>/// AES 加密///</summary>///<param name="str">明⽂(待加密)</param>///<param name="key">密⽂</param>///<returns></returns>public static string AesEncrypt(string str, string key){if (string.IsNullOrEmpty(str)) return null;Byte[] toEncryptArray = Encoding.UTF8.GetBytes(str);System.Security.Cryptography.RijndaelManaged rm = new System.Security.Cryptography.RijndaelManaged {Key = Encoding.UTF8.GetBytes(key),Mode = System.Security.Cryptography.CipherMode.ECB,Padding = System.Security.Cryptography.PaddingMode.PKCS7};System.Security.Cryptography.ICryptoTransform cTransform = rm.CreateEncryptor();Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);return Convert.ToBase64String(resultArray, 0, resultArray.Length);}///<summary>/// AES 解密///</summary>///<param name="str">明⽂(待解密)</param>///<param name="key">密⽂</param>///<returns></returns>public static string AesDecrypt(string str, string key){if (string.IsNullOrEmpty(str)) return null;Byte[] toEncryptArray = Convert.FromBase64String(str);System.Security.Cryptography.RijndaelManaged rm = new System.Security.Cryptography.RijndaelManaged {Key = Encoding.UTF8.GetBytes(key),Mode = System.Security.Cryptography.CipherMode.ECB,Padding = System.Security.Cryptography.PaddingMode.PKCS7};System.Security.Cryptography.ICryptoTransform cTransform = rm.CreateDecryptor();Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);return Encoding.UTF8.GetString(resultArray);}欢迎评论。
#include <stdlib.h>#include <stdio.h>#include <iostream>#include <string>#include <cassert>#include <Windows.h>#include <tchar.h>#include <conio.h>#include <openssl\aes.h>#include <openssl\rand.h>#include <openssl\evp.h>#pragma comment(lib,"libeay32.lib")#pragma comment(lib,"ssleay32.lib")#define BIG_TEST_SIZE 10240using namespace std;std::string EncodeAES( /*const std::string&*/char * strPassword, const std::string& strData){AES_KEY aes_key;if (AES_set_encrypt_key((const unsigned char*)strPassword, AES_BLOCK_SIZE * 8/*strlen(strPassword)*8 *//*strPassword.length() * 8*/, &aes_key) < 0){assert(false);return "";}std::string strRet;for (unsigned int i = 0; i < strData.length() / AES_BLOCK_SIZE; i++){std::string str16 = strData.substr(i*AES_BLOCK_SIZE, AES_BLOCK_SIZE);unsigned char out[AES_BLOCK_SIZE];AES_encrypt((const unsigned char*)str16.c_str(), out, &aes_key);strRet += std::string((const char*)out, AES_BLOCK_SIZE);}return strRet;}std::string EncodeAES_little( /*const std::string&*/char * strPassword, const std::string& strData) {AES_KEY aes_key;if (AES_set_encrypt_key((const unsigned char*)strPassword, AES_BLOCK_SIZE * 8/*strlen(strPassword)*8*/ /*strPassword.length() * 8*/, &aes_key) < 0)assert(false);return "";}unsigned char out[AES_BLOCK_SIZE];AES_encrypt((const unsigned char*)strData.c_str(), out, &aes_key);return std::string((const char*)out);}std::string EncodeAES_Big( /*const std::string&*/char * strPassword, const std::string& strData) {AES_KEY aes_key;if (AES_set_encrypt_key((const unsigned char*)strPassword, AES_BLOCK_SIZE * 8/*strlen(strPassword)*8 *//*strPassword.length() * 8*/, &aes_key) < 0){assert(false);return "";}std::string strRet;unsigned int i = 0;std::string str16;unsigned char out[AES_BLOCK_SIZE];for (; i < strData.length() / AES_BLOCK_SIZE; i++){str16 = strData.substr(i*AES_BLOCK_SIZE, AES_BLOCK_SIZE);AES_encrypt((const unsigned char*)str16.c_str(), out, &aes_key);strRet += std::string((const char*)out, AES_BLOCK_SIZE);}str16 = strData.substr(i*AES_BLOCK_SIZE, strData.length() - i*AES_BLOCK_SIZE);AES_encrypt((const unsigned char*)str16.c_str(), out, &aes_key);strRet += std::string((const char*)out, AES_BLOCK_SIZE);cout << "*************:" << str16 << endl;cout << "strRet.length() = " << strRet.length() << endl;return strRet;}std::string DecodeAES( /*const std::string&*/char * strPassword, const std::string& strData){AES_KEY aes_key;if (AES_set_decrypt_key((const unsigned char*)strPassword, AES_BLOCK_SIZE * 8/*strlen(strPassword)*8*/ /*strPassword.length() * 8*/, &aes_key) < 0)assert(false);return "";}std::string strRet;for (unsigned int i = 0; i < strData.length() / AES_BLOCK_SIZE; i++){std::string str16 = strData.substr(i*AES_BLOCK_SIZE, AES_BLOCK_SIZE);unsigned char out[AES_BLOCK_SIZE];AES_decrypt((const unsigned char*)str16.c_str(), out, &aes_key);strRet += std::string((const char*)out, AES_BLOCK_SIZE);}return strRet;}std::string DecodeAES_little( /*const std::string&*/char * strPassword, const std::string& strData) {AES_KEY aes_key;if (AES_set_decrypt_key((const unsigned char*)strPassword, AES_BLOCK_SIZE * 8/*strlen(strPassword)*8*/ /*strPassword.length() * 8*/, &aes_key) < 0){assert(false);return "";}unsigned char out[AES_BLOCK_SIZE];AES_decrypt((const unsigned char*)strData.c_str(), out, &aes_key);return std::string((const char*)out);}std::string DecodeAES_Big( /*const std::string&*/char * strPassword, const std::string& strData) {cout << "strData.length() = " << strData.length() << endl;AES_KEY aes_key;if (AES_set_decrypt_key((const unsigned char*)strPassword, AES_BLOCK_SIZE * 8/*strlen(strPassword)*8*/ /*strPassword.length() * 8*/, &aes_key) < 0){assert(false);return "";}std::string strRet;unsigned int i = 0;unsigned char out[AES_BLOCK_SIZE];for (; i < strData.length() / AES_BLOCK_SIZE; i++){std::string str16 = strData.substr(i*AES_BLOCK_SIZE, AES_BLOCK_SIZE);AES_decrypt((const unsigned char*)str16.c_str(), out, &aes_key);strRet += std::string((const char*)out, AES_BLOCK_SIZE);}std::string str16 = strData.substr(i*AES_BLOCK_SIZE, strData.length() - i*AES_BLOCK_SIZE);AES_decrypt((const unsigned char*)str16.c_str(), out, &aes_key);strRet += std::string((const char*)out, AES_BLOCK_SIZE);return strRet;}int main(int argc, _TCHAR* argv[]){system("cls");std::string buf;cout << "请输入待加密字符串:" << endl;getline(cin, buf);char userkey[AES_BLOCK_SIZE];//std::string userkey;RAND_pseudo_bytes((unsigned char*)userkey, sizeof userkey);std::string encrypt_data;std::string decrypt_data;cout << "输入的字符串长度与16比较大小:" << endl;if (buf.length() % 16 == 0){cout << "等于16 " << endl;encrypt_data = EncodeAES(userkey, buf);cout << "加密:" << endl;cout << encrypt_data << endl;decrypt_data = DecodeAES(userkey, encrypt_data);cout << "解密:" << endl;cout << decrypt_data << endl;}else{if (buf.length()<16){cout << "小于16 " << endl;encrypt_data = EncodeAES_little(userkey, buf);cout << "加密:" << endl;cout << encrypt_data << endl;decrypt_data = DecodeAES_little(userkey, encrypt_data);cout << "解密:" << endl;cout << decrypt_data << endl;}else{cout << "大于16 " << endl;encrypt_data = EncodeAES_Big(userkey, buf);cout << "加密:" << endl;cout << encrypt_data << endl;decrypt_data = DecodeAES_Big(userkey, encrypt_data);cout << "解密:" << endl;cout << decrypt_data << endl;}}getchar();return 0;}。
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];}```接下来,我们实现密钥扩展和子密钥生成的过程。
AES算法C语言讲解与实现
$$AES(Advanced Encryption Standard,高级加密标准)又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。
AES是一种使用密钥加密的对称性算法,可以使用128位、192位、256位三种长度的密钥,其分组处理的块(block)长度分别为128、192、256bit,由10轮、12轮和14轮加密循环组成,每轮加密循环中采用4
个复合的函数,同时增加密钥的长度。
1.生成口令
首先,在实施AES算法之前,需要生成一个口令,口令是一段由字符
组成的字符串,口令长度需要符合以下要求:128位(16字节),192位(24字节)或256位(32字节)。
2.密钥扩展
由口令生成一系列较长的子密钥。
AES使用一个迭代的函数从口令中
派生出4个较长的密码子串,这些子串以256-bit、192-bit或128-bit
形式组成,此处子串的长度与加密块的长度相同,它们是AES算法执行时
所需要的参数,具体派生步骤可参见下图:
3.加密
AES的加密算法分成10轮,每一轮加密分为三个执行步骤:字节代换、行移位和列混合。
AES解密算法与加密算法一样,也分为10轮,但是解密算法的每一
轮的步骤是加密算法的步骤的逆序。
4.结果
接着加密完成后,AES算法会产生一个新的128位的块作为加密的结果。
C#实现AES加密解密(AES-128-CBC)AES算法描述简介:DES数据加密标准算法由于密钥长度较⼩(56位),已经不适应当今分布式开放⽹络对数据加密安全性的要求,因此1997年NIST公开征集新的数据加密标准,即AES。
经过三轮的筛选,⽐利时Joan Daeman和Vincent Rijmen提交的Rijndael算法被提议为AES的最终算法。
此算法将成为美国新的数据加密标准⽽被⼴泛应⽤在各个领域中。
尽管⼈们对AES还有不同的看法,但总体来说,AES作为新⼀代的数据加密标准汇聚了强安全性、⾼性能、⾼效率、易⽤和灵活等优点。
AES设计有三个密钥长度:128,192,256位,相对⽽⾔,AES的128密钥⽐DES的56密钥强1021倍。
1using System.Security.Cryptography;2using System.IO;34class AESUtil5 {6///<summary>7/// AES加密8///</summary>9///<param name="Data">被加密的明⽂</param>10///<param name="Key">密钥</param>11///<param name="Vector">向量</param>12///<returns>密⽂</returns>13public static Byte[] AESEncrypt(Byte[] Data, String Key, String Vector)14 {15 Byte[] bKey = new Byte[32];16 Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);17 Byte[] bVector = new Byte[16];18 Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length);1920 Byte[] Cryptograph = null; // 加密后的密⽂2122 Rijndael Aes = Rijndael.Create();23try24 {25// 开辟⼀块内存流26using (MemoryStream Memory = new MemoryStream())27 {28// 把内存流对象包装成加密流对象29using (CryptoStream Encryptor = new CryptoStream(Memory,30 Aes.CreateEncryptor(bKey, bVector),31 CryptoStreamMode.Write))32 {33// 明⽂数据写⼊加密流34 Encryptor.Write(Data, 0, Data.Length);35 Encryptor.FlushFinalBlock();3637 Cryptograph = Memory.ToArray();38 }39 }40 }41catch42 {43 Cryptograph = null;44 }4546return Cryptograph;47 }4849///<summary>50/// AES解密51///</summary>52///<param name="Data">被解密的密⽂</param>53///<param name="Key">密钥</param>54///<param name="Vector">向量</param>55///<returns>明⽂</returns>56public static Byte[] AESDecrypt(Byte[] Data, String Key, String Vector)57 {58 Byte[] bKey = new Byte[32];59 Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);60 Byte[] bVector = new Byte[16];61 Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length);6263 Byte[] original = null; // 解密后的明⽂6465 Rijndael Aes = Rijndael.Create();66try67 {68// 开辟⼀块内存流,存储密⽂69using (MemoryStream Memory = new MemoryStream(Data))70 {71// 把内存流对象包装成加密流对象72using (CryptoStream Decryptor = new CryptoStream(Memory,73 Aes.CreateDecryptor(bKey, bVector),74 CryptoStreamMode.Read))75 {76// 明⽂存储区77using (MemoryStream originalMemory = new MemoryStream())78 {79 Byte[] Buffer = new Byte[1024];80 Int32 readBytes = 0;81while ((readBytes = Decryptor.Read(Buffer, 0, Buffer.Length)) > 0)82 {83 originalMemory.Write(Buffer, 0, readBytes);84 }8586 original = originalMemory.ToArray();87 }88 }89 }90 }91catch92 {93 original = null;94 }9596return original;97 }98 }。
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);。
快毕业了,最后一个课程设计,《基于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位可能造成内存溢出。