AES加解密C语言实现(任意文件长度)

合集下载

C#实现AES加密--解密

C#实现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);}欢迎评论。

C语言利用OpenSSL实现AES加解密源代码

C语言利用OpenSSL实现AES加解密源代码

#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加解密C语言程序

0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb, 0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d, 0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0xe4, 0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2, 0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25, 0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16, 0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92, 0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda, 0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84, 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a, 0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06, 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02, 0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b, 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea, 0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73, 0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85, 0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e, 0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89, 0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b, 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20, 0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4, 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31, 0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f, 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d, 0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef, 0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0, 0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61, 0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26, 0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d, }; /*The key schedule rcon table*/ static const unsigned char Rcon[10]={ 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36};

基于C++的 AES加密和解密代码

基于C++的 AES加密和解密代码

///////////头文件-------begin-----------------------------------------#ifndef AES_H_#define AES_H_#include <string>using std::string;////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////class AES{public:AES();//AES(const char *cchKey);~AES();public://加密文件数据int EncryptFile(const char *cszpSourceFileName,const char *cszpPwdFileName,const char *cszpKey);//解密文件数据int DecryptFile(const char *cszpPwdFileName,const char *cszpResultFileName,const char *cszpKey);//加密字符串string EncryptText(const char *pszInText,const char *cszpKey);//解密字符串string DecryptText(const char *pszInText,const char *cszpKey);//备份数据int BackUp(const char *cszpData, const char *cszpKey, const char *cszpFileName);//恢复备份的数据string Recover(const char *cszpKey, const char *cszpFileName);private:int ByteToBit(char ch,char bit[8]);int BitToByte(char bit[8],char *ch);int Char8ToBit64(char ch[8],char bit[64]);int Bit64ToChar8(char bit[64],char ch[8]);int DES_MakeSubKeys(char key[64],char subKeys[16][48]);int DES_PC1_Transform(char key[64], char tempbts[56]);int DES_PC2_Transform(char key[56], char tempbts[48]);int DES_ROL(char data[56], int time);int DES_IP_Transform(char data[64]);int DES_IP_1_Transform(char data[64]);int DES_E_Transform(char data[48]);int DES_P_Transform(char data[32]);int DES_SBOX(char data[48]);int DES_XOR(char R[48], char L[48],int count);int DES_Swap(char left[32],char right[32]);int DES_EncryptBlock(char plainBlock[8], char subKeys[16][48], char cipherBlock[8]);int DES_DecryptBlock(char cipherBlock[8], char subKeys[16][48], char plainBlock[8]); };#endif /* AES_H_ *////////////头文件-------end-----------------------------------------//以下是实现文件#include "stdafx.h"#include <string>#include <stdio.h>#include <memory.h>#include <time.h>#include <stdlib.h>#include "AES.h"using namespace std;#define PLAIN_FILE_OPEN_ERROR -1#define KEY_FILE_OPEN_ERROR -2#define CIPHER_FILE_OPEN_ERROR -3#define OK 1#define PARAM_ERROR -1///////////////////////////////////////////////////////////////////////////*初始置换表IP*/int IP_Table[64] = { 57,49,41,33,25,17,9,1,59,51,43,35,27,19,11,3,61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7,56,48,40,32,24,16,8,0,58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,62,54,46,38,30,22,14,6};/*逆初始置换表IP^-1*/int IP_1_Table[64] = {39,7,47,15,55,23,63,31,38,6,46,14,54,22,62,30,37,5,45,13,53,21,61,29,36,4,44,12,52,20,60,28,35,3,43,11,51,19,59,27,34,2,42,10,50,18,58,26,33,1,41,9,49,17,57,25,32,0,40,8,48,16,56,24};/*扩充置换表E*/int E_Table[48] = {31, 0, 1, 2, 3, 4,3, 4, 5, 6, 7, 8,7, 8,9,10,11,12,11,12,13,14,15,16,15,16,17,18,19,20,19,20,21,22,23,24,23,24,25,26,27,28,27,28,29,30,31, 0};/*置换函数P*/int P_Table[32] = {15,6,19,20,28,11,27,16,0,14,22,25,4,17,30,9,1,7,23,13,31,26,2,8,18,12,29,5,21,10,3,24};/*S盒*/int S[8][4][16] =/*S1*/{{{14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7}, {0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8}, {4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0}, {15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}}, /*S2*/{{15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10}, {3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5}, {0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15}, {13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9}}, /*S3*/{{10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8}, {13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1}, {13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7}, {1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12}}, /*S4*/{{7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15}, {13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9}, {10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4}, {3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14}}, /*S5*/{{2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9}, {14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6}, {4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14}, {11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3}}, /*S6*/{{12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11}, {10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8}, {9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6}, {4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13}}, /*S7*/{{4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1}, {13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6}, {1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2}, {6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12}}, /*S8*/{{13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7}, {1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2},{7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8},{2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11}}};/*置换选择1*/int PC_1[56] = {56,48,40,32,24,16,8,0,57,49,41,33,25,17,9,1,58,50,42,34,26,18,10,2,59,51,43,35,62,54,46,38,30,22,14,6,61,53,45,37,29,21,13,5,60,52,44,36,28,20,12,4,27,19,11,3};/*置换选择2*/int PC_2[48] = {13,16,10,23,0,4,2,27,14,5,20,9,22,18,11,3,25,7,15,6,26,19,12,1,40,51,30,36,46,54,29,39,50,44,32,46,43,48,38,55,33,52,45,41,49,35,28,31};/*对左移次数的规定*/int MOVE_TIMES[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};//////////////////////////////////////////////////////////////////////////AES::AES(){}// AES::AES(const char *cchKey)// {//// }AES::~AES(){}/*字节转换成二进制*/int AES::ByteToBit(char ch, char bit[8]){if (bit == NULL){return PARAM_ERROR;}int cnt = 0;for(cnt = 0;cnt < 8; cnt++){*(bit+cnt) = (ch>>cnt)&1;}return 0;}/*二进制转换成字节*/int AES::BitToByte(char bit[8],char *ch){ if ((ch == NULL) || (bit == NULL)){return PARAM_ERROR;}int cnt = 0;for(cnt = 0;cnt < 8; cnt++){*ch |= *(bit + cnt)<<cnt;}return 0;}/*将长度为8的字符串转为二进制位串*/ int AES::Char8ToBit64(char ch[8],char bit[64]){ if ((ch == NULL) || (bit == NULL)){return PARAM_ERROR;}int cnt = 0;for(cnt = 0; cnt < 8; cnt++){ByteToBit(*(ch+cnt),bit+(cnt<<3));}return 0;}/*将二进制位串转为长度为8的字符串*/ int AES::Bit64ToChar8(char bit[64],char ch[8]){ if ((ch == NULL) || (bit == NULL)){return PARAM_ERROR;}int cnt = 0;memset(ch,0,8);for(cnt = 0; cnt < 8; cnt++){BitToByte(bit+(cnt<<3),ch+cnt);}return 0;}/*生成子密钥*/int AES::DES_MakeSubKeys(char key[64],char subKeys[16][48]){if ((key == NULL) || (subKeys == NULL)){return PARAM_ERROR;}char temp[56] = {0};int cnt = 0;if(DES_PC1_Transform(key,temp) < 0)/*PC1置换*/{return -2;}for(cnt = 0; cnt < 16; cnt++){/*16轮跌代,产生16个子密钥*/DES_ROL(temp,MOVE_TIMES[cnt]);/*循环左移*/DES_PC2_Transform(temp,subKeys[cnt]);/*PC2置换,产生子密钥*/ }return 0;}/*密钥置换1*/int AES::DES_PC1_Transform(char key[64], char tempbts[56]){if ((key == NULL) || (tempbts == NULL)){return PARAM_ERROR;}int cnt = 0;for(cnt = 0; cnt < 56; cnt++){tempbts[cnt] = key[PC_1[cnt]];}return 0;}/*密钥置换2*/int AES::DES_PC2_Transform(char key[56], char tempbts[48]){if ((key == NULL) || (tempbts == NULL)){return PARAM_ERROR;}int cnt = 0;for(cnt = 0; cnt < 48; cnt++){tempbts[cnt] = key[PC_2[cnt]];}return 0;}/*循环左移*/int AES::DES_ROL(char data[56], int time){ if ((data == NULL) || (time < 0)){return PARAM_ERROR;}char temp[56] = {0};/*保存将要循环移动到右边的位*/memcpy(temp,data,time);memcpy(temp+time,data+28,time);/*前28位移动*/memcpy(data,data+time,28-time);memcpy(data+28-time,temp,time);/*后28位移动*/memcpy(data+28,data+28+time,28-time);memcpy(data+56-time,temp+time,time);return 0;}/*IP置换*/int AES::DES_IP_Transform(char data[64]){ if (data == NULL){return PARAM_ERROR;}int cnt = 0;char temp[64] = {0};for(cnt = 0; cnt < 64; cnt++){temp[cnt] = data[IP_Table[cnt]];}memcpy(data,temp,64);return 0;}/*IP逆置换*/int AES::DES_IP_1_Transform(char data[64]){ if (data == NULL){return PARAM_ERROR;}int cnt = 0;char temp[64] = {0};for(cnt = 0; cnt < 64; cnt++){temp[cnt] = data[IP_1_Table[cnt]];}memcpy(data,temp,64);return 0;}/*扩展置换*/int AES::DES_E_Transform(char data[48]){ if (data == NULL){return PARAM_ERROR;}int cnt = 0;char temp[48] = {0};for(cnt = 0; cnt < 48; cnt++){temp[cnt] = data[E_Table[cnt]];}memcpy(data,temp,48);return 0;}/*P置换*/int AES::DES_P_Transform(char data[32]){ if (data == NULL){return PARAM_ERROR;}int cnt = 0;char temp[32] = {0};for(cnt = 0; cnt < 32; cnt++){temp[cnt] = data[P_Table[cnt]];}memcpy(data,temp,32);return 0;}/*异或*/int AES::DES_XOR(char R[48], char L[48] ,int count){ if ((R == NULL) || (L == NULL)){return PARAM_ERROR;}int cnt = 0;for(cnt = 0; cnt < count; cnt++){R[cnt] ^= L[cnt];}return 0;}/*S盒置换*/int AES::DES_SBOX(char data[48]){if(data == NULL){return PARAM_ERROR;}int cnt = 0;int line = 0;int row = 0;int output = 0;int cur1 = 0,cur2 = 0;for(cnt = 0; cnt < 8; cnt++){cur1 = cnt*6;cur2 = cnt<<2;/*计算在S盒中的行与列*/line = (data[cur1]<<1) + data[cur1+5];row = (data[cur1+1]<<3) + (data[cur1+2]<<2)+ (data[cur1+3]<<1) + data[cur1+4];output = S[cnt][line][row];/*化为2进制*/data[cur2] = (output&0X08)>>3;data[cur2+1] = (output&0X04)>>2;data[cur2+2] = (output&0X02)>>1;data[cur2+3] = output&0x01;}return 0;}/*交换*/int AES::DES_Swap(char left[32], char right[32]){if((left == NULL) || (right == NULL)){return PARAM_ERROR;}char temp[32] = {0};memcpy(temp,left,32);memcpy(left,right,32);memcpy(right,temp,32);return 0;}/*加密单个分组*/int AES::DES_EncryptBlock(char plainBlock[8], char subKeys[16][48], char cipherBlock[8]){if((plainBlock == NULL) || (subKeys == NULL) || (cipherBlock == NULL)){return PARAM_ERROR;}char plainBits[64] = {0};char copyRight[48] = {0};int cnt = 0;Char8ToBit64(plainBlock,plainBits);/*初始置换(IP置换)*/DES_IP_Transform(plainBits);/*16轮迭代*/for(cnt = 0; cnt < 16; cnt++){memcpy(copyRight,plainBits+32,32);/*将右半部分进行扩展置换,从32位扩展到48位*/DES_E_Transform(copyRight);/*将右半部分与子密钥进行异或操作*/DES_XOR(copyRight,subKeys[cnt],48);/*异或结果进入S盒,输出32位结果*/DES_SBOX(copyRight);/*P置换*/DES_P_Transform(copyRight);/*将明文左半部分与右半部分进行异或*/DES_XOR(plainBits,copyRight,32);if(cnt != 15){/*最终完成左右部的交换*/DES_Swap(plainBits,plainBits+32);}}/*逆初始置换(IP^1置换)*/DES_IP_1_Transform(plainBits);Bit64ToChar8(plainBits,cipherBlock);return 0;}/*解密单个分组*/int AES::DES_DecryptBlock(char cipherBlock[8], char subKeys[16][48],char plainBlock[8]){ if((plainBlock == NULL) || (subKeys == NULL) || (cipherBlock == NULL)){return PARAM_ERROR;}char cipherBits[64] = {0};char copyRight[48] = {0};int cnt = 0;Char8ToBit64(cipherBlock,cipherBits);/*初始置换(IP置换)*/DES_IP_Transform(cipherBits);/*16轮迭代*/for(cnt = 15; cnt >= 0; cnt--){memcpy(copyRight,cipherBits+32,32);/*将右半部分进行扩展置换,从32位扩展到48位*/DES_E_Transform(copyRight);/*将右半部分与子密钥进行异或操作*/DES_XOR(copyRight,subKeys[cnt],48);/*异或结果进入S盒,输出32位结果*/DES_SBOX(copyRight);/*P置换*/DES_P_Transform(copyRight);/*将明文左半部分与右半部分进行异或*/DES_XOR(cipherBits,copyRight,32);if(cnt != 0){/*最终完成左右部的交换*/DES_Swap(cipherBits,cipherBits+32);}}/*逆初始置换(IP^1置换)*/DES_IP_1_Transform(cipherBits);Bit64ToChar8(cipherBits,plainBlock);return 0;}/*功能:加密文件参数:[cszpSourceFileName]:原数据文件名[cszpPwdFileName]:密码文件名[cszpKey]:密码*/int AES::EncryptFile(const char *cszpSourceFileName,const char *cszpPwdFileName,const char *cszpKey){if ((cszpSourceFileName == NULL) ||(cszpPwdFileName == NULL) ||(cszpKey == NULL)){return PARAM_ERROR;}FILE *plain = NULL,*cipher = NULL;int count = 0;char plainBlock[8] = {0};char cipherBlock[8] = {0};char keyBlock[8] = {0};char bKey[64] = {0};char subKeys[16][48] = {0};if((plain = fopen(cszpSourceFileName,("rb"))) == NULL){ return PLAIN_FILE_OPEN_ERROR;}if((cipher = fopen(cszpPwdFileName,"wb")) == NULL){ return CIPHER_FILE_OPEN_ERROR;}/*设置密钥*/memcpy(keyBlock,cszpKey,8);/*将密钥转换为二进制流*/Char8ToBit64(keyBlock,bKey);/*生成子密钥*/DES_MakeSubKeys(bKey,subKeys);while(!feof(plain)){/*每次读8个字节,并返回成功读取的字节数*/if((count = fread(plainBlock,sizeof(char),8,plain)) == 8){DES_EncryptBlock(plainBlock,subKeys,cipherBlock);fwrite(cipherBlock,sizeof(char),8,cipher);}}if(count){/*填充*/memset(plainBlock + count,'\0',7 - count);/*最后一个字符保存包括最后一个字符在内的所填充的字符数量*/plainBlock[7] = 8 - count;DES_EncryptBlock(plainBlock,subKeys,cipherBlock);fwrite(cipherBlock,sizeof(char),8,cipher);}fclose(plain);plain = NULL;fclose(cipher);cipher = NULL;return OK;}/*功能:解密文件参数:[cszpPwdFileName]:密码文件名[cszpResultFileName]:解密后数据文件名[cszpKey]:密码*/int AES::DecryptFile(const char *cszpPwdFileName,const char *cszpResultFileName,const char *cszpKey){if ((cszpResultFileName == NULL) ||(cszpPwdFileName == NULL) ||(cszpKey == NULL)){return PARAM_ERROR;}FILE *plain = NULL, *cipher = NULL;int count,times = 0;long fileLen = 0;char plainBlock[8] = {0};char cipherBlock[8] = {0};char keyBlock[8] = {0};char bKey[64] = {0};char subKeys[16][48] = {0};if((cipher = fopen(cszpPwdFileName,"rb")) == NULL){ return CIPHER_FILE_OPEN_ERROR;}if((plain = fopen(cszpResultFileName,"wb")) == NULL){ return PLAIN_FILE_OPEN_ERROR;}/*设置密钥*/memcpy(keyBlock,cszpKey,8);/*将密钥转换为二进制流*/Char8ToBit64(keyBlock,bKey);/*生成子密钥*/DES_MakeSubKeys(bKey,subKeys);/*取文件长度*/fseek(cipher,0,SEEK_END);/*将文件指针置尾*/ fileLen = ftell(cipher); /*取文件指针当前位置*/ rewind(cipher); /*将文件指针重指向文件头*/while(1){/*密文的字节数一定是8的整数倍*/fread(cipherBlock,sizeof(char),8,cipher);DES_DecryptBlock(cipherBlock,subKeys,plainBlock);times += 8;if(times < fileLen){fwrite(plainBlock,sizeof(char),8,plain);}else{break;}}/*判断末尾是否被填充*/if(plainBlock[7] < 8){for(count = 8 - plainBlock[7]; count < 7; count++){if(plainBlock[count] != '\0'){break;}}}if(count == 7){/*有填充*/fwrite(plainBlock,sizeof(char),8 - plainBlock[7],plain);}else{/*无填充*/fwrite(plainBlock,sizeof(char),8,plain);}fclose(plain);plain = NULL;fclose(cipher);cipher = NULL;return OK;}/*功能:加密字符串参数:[pszInText]:要加密的字符串[cszpKey]:密码*/string AES::EncryptText(const char *pszInText,const char *cszpKey){if ((pszInText == NULL) ||(cszpKey == NULL)){return "";}int count = 0;char plainBlock[9] = {0};char cipherBlock[9] = {0};char keyBlock[9] = {0};char bKey[64] = {0};char subKeys[16][48] = {0};int nSize = strlen(pszInText);char *pchData = (char *)malloc(nSize + 1);if (pchData == NULL){return "";}memset(pchData, 0, nSize + 1);memcpy(pchData, pszInText, nSize);/*设置密钥*/memcpy(keyBlock,cszpKey,8);/*将密钥转换为二进制流*/Char8ToBit64(keyBlock,bKey);/*生成子密钥*/DES_MakeSubKeys(bKey,subKeys);string strData;char *pch = pchData;do{memset(plainBlock, 0, 9);memcpy(plainBlock, pch, 8);int nLen = strlen(plainBlock);if (nLen < 8){count = nLen;break;}else{DES_EncryptBlock(plainBlock,subKeys,cipherBlock);strData += cipherBlock;pch += 8;}} while (true);if(count){/*填充*/memset(plainBlock + count,'\0',7 - count);/*最后一个字符保存包括最后一个字符在内的所填充的字符数量*/ plainBlock[7] = 8 - count;DES_EncryptBlock(plainBlock,subKeys,cipherBlock);strData += cipherBlock;}return strData;}/*功能:解密字符串参数:[pszInText]:要解密的字符串,即加密后的字符串[cszpKey]:密码*/string AES::DecryptText(const char *pszInText,const char *cszpKey) {if ((pszInText == NULL) ||(cszpKey == NULL)){return "";}int count = 0;int times = 0;char plainBlock[9] = {0};char cipherBlock[9] = {0};char keyBlock[9] = {0};char bKey[64] = {0};char subKeys[16][48] = {0};int nSize = strlen(pszInText);char *pchData = (char *)malloc(nSize + 1);if (pchData == NULL){return "";}memset(pchData, 0, nSize + 1);memcpy(pchData, pszInText, nSize);/*设置密钥*/memcpy(keyBlock,cszpKey,8);/*将密钥转换为二进制流*/Char8ToBit64(keyBlock,bKey);/*生成子密钥*/DES_MakeSubKeys(bKey,subKeys);string strData;char *pch = pchData;while(true){/*密文的字节数一定是8的整数倍*/memset(cipherBlock, 0, 9);memset(plainBlock, 0, 9);memcpy(cipherBlock,pch,8);DES_DecryptBlock(cipherBlock,subKeys,plainBlock);times += 8;pch += 8;if(times < nSize){strData += plainBlock;}else{break;}}/*判断末尾是否被填充*/if(plainBlock[7] < 8){for(count = 8 - plainBlock[7]; count < 7; count++){if(plainBlock[count] != '\0'){break;}}}if(count == 7){/*有填充*/memset(cipherBlock, 0, 9);memcpy(cipherBlock,plainBlock,8 - plainBlock[7]);strData += cipherBlock;}else{/*无填充*/memset(cipherBlock, 0, 9);memcpy(cipherBlock,plainBlock,8);strData += cipherBlock;}return strData;}/*功能:备份数据至指定的文件中参数:【cszpData】:要备份的数据【cszpKey】:用于对数据加密的密码【cszpFileName】:保存数据的文件名返回值:成功:大于等于零(>=0)失败:小于零(<0)*/int AES::BackUp(const char *cszpData, const char *cszpKey, const char *cszpFileName) {if ((cszpData == NULL) ||(cszpKey == NULL) ||(cszpFileName == NULL)){return PARAM_ERROR;}string strData = EncryptText(cszpData, cszpKey);if (strData.empty()){return -2;}FILE *pfile = NULL;if((pfile = fopen(cszpFileName,"wb")) == NULL){return CIPHER_FILE_OPEN_ERROR;}fwrite(strData.c_str(), strlen(strData.c_str()), 1, pfile);fclose(pfile);pfile = NULL;return 0;}//恢复备份的数据/*功能:从指定的文件中恢复备份的数据参数:【cszpKey】:用于对数据解密的密码【cszpFileName】:保存数据的文件名返回值:成功:解密后的数据失败:空值*/string AES::Recover(const char *cszpKey, const char *cszpFileName) {if ((cszpKey == NULL) || (cszpFileName == NULL)){return "";}string strData;FILE *pfile = NULL;if ((pfile = fopen(cszpFileName, "rb")) == NULL){return "";}/*取文件长度*/fseek(pfile,0,SEEK_END);/*将文件指针置尾*/long fileLen = ftell(pfile); /*取文件指针当前位置*/rewind(pfile); /*将文件指针重指向文件头*/char *szpFileData = (char *)malloc(fileLen + 1);if (szpFileData == NULL){fclose(pfile);pfile = NULL;return "";}memset(szpFileData, 0, fileLen + 1);fread(szpFileData, fileLen, 1, pfile);fclose(pfile);strData = DecryptText(szpFileData, cszpKey);return strData;}。

AES算法C语言讲解与实现

AES算法C语言讲解与实现

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位的块作为加密的结果。

AES加密C语言实现代码

AES加密C语言实现代码

#define BPOLY 0x1b //!< Lower 8 bits of (x^8+x^4+x^3+x+1), ie. (x^4+x^3+x+1).#define BLOCKSIZE 16 //!< Block size in number of bytes.#define KEY_COUNT 3#if KEY_COUNT == 1#define KEYBITS 128 //!< Use AES128.#elif KEY_COUNT == 2#define KEYBITS 192 //!< Use AES196.#elif KEY_COUNT == 3#define KEYBITS 256 //!< Use AES256.#else#error Use 1, 2 or 3 keys!#endif#if KEYBITS == 128#define ROUNDS 10 //!< Number of rounds.#define KEYLENGTH 16 //!< Key length in number of bytes.#elif KEYBITS == 192#define ROUNDS 12 //!< Number of rounds.#define KEYLENGTH 24 //!< // Key length in number of bytes.#elif KEYBITS == 256#define ROUNDS 14 //!< Number of rounds.#define KEYLENGTH 32 //!< Key length in number of bytes.#else#error Key must be 128, 192 or 256 bits!#endif#define EXPANDED_KEY_SIZE (BLOCKSIZE * (ROUNDS+1)) //!< 176, 208 or 240 bytes.unsigned char AES_Key_Table[32] ={0xd0, 0x94, 0x3f, 0x8c, 0x29, 0x76, 0x15, 0xd8,0x20, 0x40, 0xe3, 0x27, 0x45, 0xd8, 0x48, 0xad,0xea, 0x8b, 0x2a, 0x73, 0x16, 0xe9, 0xb0, 0x49,0x45, 0xb3, 0x39, 0x28, 0x0a, 0xc3, 0x28, 0x3c,};unsigned char block1[256]; //!< Workspace 1.unsigned char block2[256]; //!< Worksapce 2.unsigned char tempbuf[256];unsigned char *powTbl; //!< Final location of exponentiation lookup table.unsigned char *logTbl; //!< Final location of logarithm lookup table. unsigned char *sBox; //!< Final location of s-box.unsigned char *sBoxInv; //!< Final location of inverse s-box. unsigned char *expandedKey; //!< Final location of expanded key.void CalcPowLog(unsigned char *powTbl, unsigned char *logTbl) {unsigned char i = 0;unsigned char t = 1;do {// Use 0x03 as root for exponentiation and logarithms.powTbl[i] = t;logTbl[t] = i;i++;// Muliply t by 3 in GF(2^8).t ^= (t << 1) ^ (t & 0x80 ? BPOLY : 0);}while( t != 1 ); // Cyclic properties ensure that i < 255.powTbl[255] = powTbl[0]; // 255 = '-0', 254 = -1, etc.}void CalcSBox( unsigned char * sBox ){unsigned char i, rot;unsigned char temp;unsigned char result;// Fill all entries of sBox[].i = 0;do {//Inverse in GF(2^8).if( i > 0 ){temp = powTbl[ 255 - logTbl[i] ];}else{temp = 0;}// Affine transformation in GF(2).result = temp ^ 0x63; // Start with adding a vector in GF(2).for( rot = 0; rot < 4; rot++ ){// Rotate left.temp = (temp<<1) | (temp>>7);// Add rotated byte in GF(2).result ^= temp;}// Put result in table.sBox[i] = result;} while( ++i != 0 );}void CalcSBoxInv( unsigned char * sBox, unsigned char * sBoxInv ) {unsigned char i = 0;unsigned char j = 0;// Iterate through all elements in sBoxInv using i.do {// Search through sBox using j.do {// Check if current j is the inverse of current i.if( sBox[ j ] == i ){// If so, set sBoxInc and indicate search finished.sBoxInv[ i ] = j;j = 255;}} while( ++j != 0 );} while( ++i != 0 );}void CycleLeft( unsigned char * row ){// Cycle 4 bytes in an array left once.unsigned char temp = row[0];row[0] = row[1];row[1] = row[2];row[2] = row[3];row[3] = temp;}void InvMixColumn( unsigned char * column ){unsigned char r0, r1, r2, r3;r0 = column[1] ^ column[2] ^ column[3];r1 = column[0] ^ column[2] ^ column[3];r2 = column[0] ^ column[1] ^ column[3];r3 = column[0] ^ column[1] ^ column[2];column[0] = (column[0] << 1) ^ (column[0] & 0x80 ? BPOLY : 0);column[1] = (column[1] << 1) ^ (column[1] & 0x80 ? BPOLY : 0);column[2] = (column[2] << 1) ^ (column[2] & 0x80 ? BPOLY : 0);column[3] = (column[3] << 1) ^ (column[3] & 0x80 ? BPOLY : 0);r0 ^= column[0] ^ column[1];r1 ^= column[1] ^ column[2];r2 ^= column[2] ^ column[3];r3 ^= column[0] ^ column[3];column[0] = (column[0] << 1) ^ (column[0] & 0x80 ? BPOLY : 0);column[1] = (column[1] << 1) ^ (column[1] & 0x80 ? BPOLY : 0);column[2] = (column[2] << 1) ^ (column[2] & 0x80 ? BPOLY : 0);column[3] = (column[3] << 1) ^ (column[3] & 0x80 ? BPOLY : 0);r0 ^= column[0] ^ column[2];r1 ^= column[1] ^ column[3];r2 ^= column[0] ^ column[2];r3 ^= column[1] ^ column[3];column[0] = (column[0] << 1) ^ (column[0] & 0x80 ? BPOLY : 0);column[1] = (column[1] << 1) ^ (column[1] & 0x80 ? BPOLY : 0);column[2] = (column[2] << 1) ^ (column[2] & 0x80 ? BPOLY : 0);column[3] = (column[3] << 1) ^ (column[3] & 0x80 ? BPOLY : 0);column[0] ^= column[1] ^ column[2] ^ column[3];r0 ^= column[0];r1 ^= column[0];r2 ^= column[0];r3 ^= column[0];column[0] = r0;column[1] = r1;column[2] = r2;column[3] = r3;}void SubBytes( unsigned char * bytes, unsigned char count ){do {*bytes = sBox[ *bytes ]; // Substitute every byte in state.bytes++;} while( --count );}void InvSubBytesAndXOR( unsigned char * bytes, unsigned char * key, unsigned char count ){do {// *bytes = sBoxInv[ *bytes ] ^ *key; // Inverse substitute every byte in state and add key.*bytes = block2[ *bytes ] ^ *key; // Use block2 directly. Increases speed.bytes++;key++;} while( --count );}void InvShiftRows( unsigned char * state ){unsigned char temp;// Note: State is arranged column by column.// Cycle second row right one time.temp = state[ 1 + 3*4 ];state[ 1 + 3*4 ] = state[ 1 + 2*4 ];state[ 1 + 2*4 ] = state[ 1 + 1*4 ];state[ 1 + 1*4 ] = state[ 1 + 0*4 ];state[ 1 + 0*4 ] = temp;// Cycle third row right two times.temp = state[ 2 + 0*4 ];state[ 2 + 0*4 ] = state[ 2 + 2*4 ];state[ 2 + 2*4 ] = temp;temp = state[ 2 + 1*4 ];state[ 2 + 1*4 ] = state[ 2 + 3*4 ];state[ 2 + 3*4 ] = temp;// Cycle fourth row right three times, ie. left once.temp = state[ 3 + 0*4 ];state[ 3 + 0*4 ] = state[ 3 + 1*4 ];state[ 3 + 1*4 ] = state[ 3 + 2*4 ];state[ 3 + 2*4 ] = state[ 3 + 3*4 ];state[ 3 + 3*4 ] = temp;}void InvMixColumns( unsigned char * state ){InvMixColumn( state + 0*4 );InvMixColumn( state + 1*4 );InvMixColumn( state + 2*4 );InvMixColumn( state + 3*4 );}void XORBytes( unsigned char * bytes1, unsigned char * bytes2, unsigned char count ) {do {*bytes1 ^= *bytes2; // Add in GF(2), ie. XOR.bytes1++;bytes2++;} while( --count );}void CopyBytes( unsigned char * to, unsigned char * from, unsigned char count ) {do {*to = *from;to++;from++;} while( --count );}void KeyExpansion( unsigned char * expandedKey ){unsigned char temp[4];unsigned char i;unsigned char Rcon[4] = { 0x01, 0x00, 0x00, 0x00 }; // Round constant.unsigned char * key = AES_Key_Table;// Copy key to start of expanded key.i = KEYLENGTH;do {*expandedKey = *key;expandedKey++;key++;} while( --i );// Prepare last 4 bytes of key in temp.expandedKey -= 4;temp[0] = *(expandedKey++);temp[1] = *(expandedKey++);temp[2] = *(expandedKey++);temp[3] = *(expandedKey++);// Expand key.i = KEYLENGTH;while( i < BLOCKSIZE*(ROUNDS+1) ){// Are we at the start of a multiple of the key size?if( (i % KEYLENGTH) == 0 ){CycleLeft( temp ); // Cycle left once.SubBytes( temp, 4 ); // Substitute each byte.XORBytes( temp, Rcon, 4 ); // Add constant in GF(2).*Rcon = (*Rcon << 1) ^ (*Rcon & 0x80 ? BPOLY : 0);}// Keysize larger than 24 bytes, ie. larger that 192 bits?#if KEYLENGTH > 24// Are we right past a block size?else if( (i % KEYLENGTH) == BLOCKSIZE ) {SubBytes( temp, 4 ); // Substitute each byte.}#endif// Add bytes in GF(2) one KEYLENGTH away.XORBytes( temp, expandedKey - KEYLENGTH, 4 );// Copy result to current 4 bytes.*(expandedKey++) = temp[ 0 ];*(expandedKey++) = temp[ 1 ];*(expandedKey++) = temp[ 2 ];*(expandedKey++) = temp[ 3 ];i += 4; // Next 4 bytes.}}void InvCipher( unsigned char * block, unsigned char * expandedKey ) {unsigned char round = ROUNDS-1;expandedKey += BLOCKSIZE * ROUNDS;XORBytes( block, expandedKey, 16 );expandedKey -= BLOCKSIZE;do {InvShiftRows( block );InvSubBytesAndXOR( block, expandedKey, 16 );expandedKey -= BLOCKSIZE;InvMixColumns( block );} while( --round );InvShiftRows( block );InvSubBytesAndXOR( block, expandedKey, 16 );}void aesDecInit(void){powTbl = block1;logTbl = block2;CalcPowLog( powTbl, logTbl );sBox = tempbuf;CalcSBox( sBox );expandedKey = block1;KeyExpansion( expandedKey );sBoxInv = block2; // Must be block2.CalcSBoxInv( sBox, sBoxInv );}void aesDecrypt( unsigned char * buffer, unsigned char * chainBlock ) {unsigned char temp[ BLOCKSIZE ];CopyBytes( temp, buffer, BLOCKSIZE );InvCipher( buffer, expandedKey );XORBytes( buffer, chainBlock, BLOCKSIZE );CopyBytes( chainBlock, temp, BLOCKSIZE );}unsigned char Multiply( unsigned char num, unsigned char factor ){unsigned char mask = 1;unsigned char result = 0;while( mask != 0 ){// Check bit of factor given by mask.if( mask & factor ){// Add current multiple of num in GF(2).result ^= num;}// Shift mask to indicate next bit.mask <<= 1;// Double num.num = (num << 1) ^ (num & 0x80 ? BPOLY : 0);}return result;}unsigned char DotProduct( unsigned char * vector1, unsigned char * vector2 ) {unsigned char result = 0;result ^= Multiply( *vector1++, *vector2++ );result ^= Multiply( *vector1++, *vector2++ );result ^= Multiply( *vector1++, *vector2++ );result ^= Multiply( *vector1 , *vector2 );return result;}void MixColumn( unsigned char * column ){unsigned char row[8] = {0x02, 0x03, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01};// Prepare first row of matrix twice, to eliminate need for cycling.unsigned char result[4];// Take dot products of each matrix row and the column vector.result[0] = DotProduct( row+0, column );result[1] = DotProduct( row+3, column );result[2] = DotProduct( row+2, column );result[3] = DotProduct( row+1, column );// Copy temporary result to original column.column[0] = result[0];column[1] = result[1];column[2] = result[2];column[3] = result[3];}void MixColumns( unsigned char * state ){MixColumn( state + 0*4 );MixColumn( state + 1*4 );MixColumn( state + 2*4 );MixColumn( state + 3*4 );}void ShiftRows( unsigned char * state ){unsigned char temp;// Note: State is arranged column by column.// Cycle second row left one time.temp = state[ 1 + 0*4 ];state[ 1 + 0*4 ] = state[ 1 + 1*4 ];state[ 1 + 1*4 ] = state[ 1 + 2*4 ];state[ 1 + 2*4 ] = state[ 1 + 3*4 ];state[ 1 + 3*4 ] = temp;// Cycle third row left two times.temp = state[ 2 + 0*4 ];state[ 2 + 0*4 ] = state[ 2 + 2*4 ];state[ 2 + 2*4 ] = temp;temp = state[ 2 + 1*4 ];state[ 2 + 1*4 ] = state[ 2 + 3*4 ];state[ 2 + 3*4 ] = temp;// Cycle fourth row left three times, ie. right once.temp = state[ 3 + 3*4 ];state[ 3 + 3*4 ] = state[ 3 + 2*4 ];state[ 3 + 2*4 ] = state[ 3 + 1*4 ];state[ 3 + 1*4 ] = state[ 3 + 0*4 ];state[ 3 + 0*4 ] = temp;}void Cipher( unsigned char * block, unsigned char * expandedKey ) {unsigned char round = ROUNDS-1;XORBytes( block, expandedKey, 16 );expandedKey += BLOCKSIZE;do {SubBytes( block, 16 );ShiftRows( block );MixColumns( block );XORBytes( block, expandedKey, 16 );expandedKey += BLOCKSIZE;} while( --round );SubBytes( block, 16 );ShiftRows( block );XORBytes( block, expandedKey, 16 );}void aesEncInit(void){powTbl = block1;logTbl = tempbuf;CalcPowLog( powTbl, logTbl );sBox = block2;CalcSBox( sBox );expandedKey = block1;KeyExpansion( expandedKey );}void aesEncrypt( unsigned char * buffer, unsigned char * chainBlock ) {XORBytes( buffer, chainBlock, BLOCKSIZE );Cipher( buffer, expandedKey );CopyBytes( chainBlock, buffer, BLOCKSIZE );}#include <string.h>void AES_Test(void){unsigned char dat[16]="0123456789ABCDEF";unsigned char chainCipherBlock[16];unsigned char i;for(i=0;i<32;i++) AES_Key_Table[i]=i;//做运算之前先要设置好密钥,这里只是设置密钥的DEMO。

AES加密解密C语言实现

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位可能造成内存溢出。

AES算法的C语言实现

AES算法的C语言实现
( (uint32) MUL( 0x09, y ) << 16 ) ^
( (uint32) MUL( 0x0E, y ) << 24 );
RT0[i] &= 0xFFFFFFFF;
RT1[i] = ROTR8( RT0[i] );
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, uint32 Fra bibliotekT3[256];
/* reverse S-box & tables */
uint32 RSb[256];
uint32 RT0[256];
uint32 RT1[256];
uint32 RT2[256];
uint32 RT3[256];
/* round constants */
0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
x ^= y; y = ( y << 1 ) | ( y >> 7 );
x ^= y ^ 0x63;
FSb[i] = x;
RSb[x] = i;
}
/* generate the forward and reverse tables */

AES加密和解密文件

AES加密和解密文件

AES加密和解密⽂件using System;using System.IO;using System.Security;using System.Security.Cryptography;using System.Runtime.InteropServices;using System.Text;namespace CSEncryptDecrypt{class Class1{// Call this function to remove the key from memory after use for security[System.Runtime.InteropServices.DllImport("KERNEL32.DLL", EntryPoint="RtlZeroMemory")]public static extern bool ZeroMemory(IntPtr Destination, int Length);// Function to Generate a 64 bits Key.static string GenerateKey(){// Create an instance of Symetric Algorithm. Key and IV is generated automatically.DESCryptoServiceProvider desCrypto =(DESCryptoServiceProvider)DESCryptoServiceProvider.Create(); // Use the Automatically generated key for Encryption.return ASCIIEncoding.ASCII.GetString(desCrypto.Key);}static void EncryptFile(string sInputFilename,string sOutputFilename,string sKey){FileStream fsInput = new FileStream(sInputFilename,FileMode.Open,FileAccess.Read);FileStream fsEncrypted = new FileStream(sOutputFilename,FileMode.Create,FileAccess.Write);DESCryptoServiceProvider DES = new DESCryptoServiceProvider();DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);ICryptoTransform desencrypt = DES.CreateEncryptor();CryptoStream cryptostream = new CryptoStream(fsEncrypted,desencrypt,CryptoStreamMode.Write);byte[] bytearrayinput = new byte[fsInput.Length];fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);cryptostream.Close();fsInput.Close();fsEncrypted.Close();}static void DecryptFile(string sInputFilename,string sOutputFilename,string sKey){DESCryptoServiceProvider DES = new DESCryptoServiceProvider();//A 64 bit key and IV is required for this provider.//Set secret key For DES algorithm.DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);//Set initialization vector.DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);//Create a file stream to read the encrypted file back.FileStream fsread = new FileStream(sInputFilename,FileMode.Open,FileAccess.Read);//Create a DES decryptor from the DES instance.ICryptoTransform desdecrypt = DES.CreateDecryptor();//Create crypto stream set to read and do a//DES decryption transform on incoming bytes.CryptoStream cryptostreamDecr = new CryptoStream(fsread,desdecrypt,CryptoStreamMode.Read);//Print the contents of the decrypted file.StreamWriter fsDecrypted = new StreamWriter(sOutputFilename);fsDecrypted.Write(new StreamReader(cryptostreamDecr).ReadToEnd());fsDecrypted.Flush();fsDecrypted.Close();}static void Main(){// Must be 64 bits, 8 bytes.// Distribute this key to the user who will decrypt this file.string sSecretKey;// Get the Key for the file to Encrypt.sSecretKey = GenerateKey();// For additional security Pin the key.GCHandle gch = GCHandle.Alloc( sSecretKey,GCHandleType.Pinned );// Encrypt the file.EncryptFile(@"C:\MyData.txt",@"C:\Encrypted.txt",sSecretKey);// Decrypt the file.DecryptFile(@"C:\Encrypted.txt",@"C:\Decrypted.txt",sSecretKey);// Remove the Key from memory.ZeroMemory(gch.AddrOfPinnedObject(), sSecretKey.Length * 2);gch.Free();}}}----------------------------------------------------------------------------------------------------------⼤⽂件分块加密和解密using System.Text;using System.Collections;using ponentModel;using System.Data;using ;using .Sockets;using System.Threading;using System.IO;using System.Security.Cryptography;namespace VideoEncrypt{class Program{static void Main(string[] args){RijndaelManaged rij = new RijndaelManaged();rij.KeySize = 128;string fp = @"E://friends//3//3.mkv";string sPhysicalFilePath = @"E://friends//3//o3.mkv";string fw = @"E://friends//3//dd3.mkv";Console.WriteLine("Encrypting begin...");encryption(rij, fp, sPhysicalFilePath);decryption(rij,sPhysicalFilePath,fw);}//⽤于加密的函数public static void encryption(RijndaelManaged rij,string readfile, string writefile){try{byte[] key = rij.Key;byte[] iv = rij.IV;byte[] buffer = new byte[4096];Rijndael crypt = Rijndael.Create();ICryptoTransform transform = crypt.CreateEncryptor(key, iv);//写进⽂件FileStream fswrite = new FileStream(writefile, FileMode.Create);CryptoStream cs = new CryptoStream(fswrite, transform, CryptoStreamMode.Write); //打开⽂件FileStream fsread = new FileStream(readfile, FileMode.Open);int length;//while ((length = fsread.ReadByte()) != -1)//cs.WriteByte((byte)length);while ((length = fsread.Read(buffer, 0, 4096)) > 0)cs.Write(buffer, 0, (int)length);fsread.Close();cs.Close();fswrite.Close();Console.WriteLine("Encrypt Success");}catch (Exception e){Console.WriteLine("Encrypt Faile"+e.ToString());}}//⽤于解密的函数public static void decryption(RijndaelManaged rij, string readfile, string writefile){try{byte[] key = rij.Key;byte[] iv = rij.IV;byte[] buffer=new byte[4096];Rijndael crypt = Rijndael.Create();ICryptoTransform transform = crypt.CreateDecryptor(key, iv);//读取加密后的⽂件FileStream fsopen = new FileStream(readfile, FileMode.Open);CryptoStream cs = new CryptoStream(fsopen, transform, CryptoStreamMode.Read); //把解密后的结果写进⽂件FileStream fswrite = new FileStream(writefile, FileMode.OpenOrCreate);int length;//while ((length = cs.ReadByte()) != -1)//fswrite.WriteByte((byte)length);while ((length = cs.Read(buffer, 0, 4096)) > 0)fswrite.Write(buffer, 0, (int)length);fswrite.Close();cs.Close();fsopen.Close();Console.WriteLine("Decrypt Success");}catch (Exception e){Console.WriteLine("Decrypt Failed"+e.ToString());}}}}。

AES加密C语言实现代码

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);。

C语言利用OpenSSL实现AES加解密源代码

C语言利用OpenSSL实现AES加解密源代码

#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语言实现(VC版)

AES加解密算法的C语言实现(VC版)
*
* 3 pre-rotated to save the ROTL8, ROTL16 and ROTL24 overhead */
void encrypt(char *buff)
{
int i,j,k,m;
WORD a[8],b[8],*x,*y,*t;
for (i=j=0;i<Nb;i++,j+=4)
by=by>>4 &0x0f;
if(by >= 0 && by <= 9)
*str++ = by + '0';
else if(by >= 0x0A && by <= 0x0F)
*str++ = by - 10 + 'A';
by = *hex++;
by=by &0x0f;
if(by >= 0 && by <= 9)
else
return 0;
}
static WORD SubByte(WORD a)
{
BYTE b[4];
unpack(a,b);
b[0]=fbsub[b[0]];
b[1]=fbsub[b[1]];
b[2]=fbsub[b[2]];
b[3]=fbsub[b[3]];
return pack(b);
}
static BYTE product(WORD x,WORD y)
{ /* unpack bytes from a word */
b[0]=(BYTE)a; b[1]=(BYTE)(a>>8);

AES加密算法C++实现

AES加密算法C++实现

AES加密算法C++实现 我从⽹上下载了⼀套AES加密算法的C++实现,代码如下:(1)aes.h#ifndef SRC_UTILS_AES_H#define SRC_UTILS_AES_Hclass AES{public:AES(unsigned char* key);virtual ~AES();unsigned char* Cipher(unsigned char* input); // 加密,传⼊的数组⼤⼩必须是16字节unsigned char* InvCipher(unsigned char* input); // 解密,传⼊的数组也必须是16字节void* Cipher(void* input, int length=0); // 可以传⼊数组,⼤⼩必须是16的整数倍,如果不是将会越界操作;如果不传length⽽默认为0,那么将按照字符串处理,遇'\0'结束void* InvCipher(void* input, int length); // 必须传⼊数组和⼤⼩,必须是16的整数倍private:unsigned char Sbox[256];unsigned char InvSbox[256];unsigned char w[11][4][4];void KeyExpansion(unsigned char* key, unsigned char w[][4][4]);unsigned char FFmul(unsigned char a, unsigned char b);void SubBytes(unsigned char state[][4]);void ShiftRows(unsigned char state[][4]);void MixColumns(unsigned char state[][4]);void AddRoundKey(unsigned char state[][4], unsigned char k[][4]);void InvSubBytes(unsigned char state[][4]);void InvShiftRows(unsigned char state[][4]);void InvMixColumns(unsigned char state[][4]);};#endif// SRC_UTILS_AES_H(2)aes.cpp1 #include "aes.h"2 #include "string.h"34 AES::AES(unsigned char* key)5 {6 unsigned char sBox[] =7 { /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */80x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76, /*0*/90xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0, /*1*/100xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15, /*2*/110x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75, /*3*/120x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84, /*4*/130x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf, /*5*/140xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8, /*6*/150x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2, /*7*/160xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73, /*8*/170x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb, /*9*/180xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79, /*a*/190xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08, /*b*/200xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a, /*c*/210x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e, /*d*/220xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf, /*e*/230x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16/*f*/24 };25 unsigned char invsBox[256] =26 { /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */270x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb, /*0*/280x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb, /*1*/290x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e, /*2*/300x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25, /*3*/310x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92, /*4*/320x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84, /*5*/330x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06, /*6*/340xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b, /*7*/350x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73, /*8*/360x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e, /*9*/370x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b, /*a*/380xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4, /*b*/390x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f, /*c*/400x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef, /*d*/410xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61, /*e*/420x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d/*f*/43 };44 memcpy(Sbox, sBox, 256);45 memcpy(InvSbox, invsBox, 256);46 KeyExpansion(key, w);47 }49 AES::~AES()50 {5152 }5354 unsigned char* AES::Cipher(unsigned char* input)55 {56 unsigned char state[4][4];57int i,r,c;5859for(r=0; r<4; r++)60 {61for(c=0; c<4 ;c++)62 {63 state[r][c] = input[c*4+r];64 }65 }6667 AddRoundKey(state,w[0]);6869for(i=1; i<=10; i++)70 {71 SubBytes(state);72 ShiftRows(state);73if(i!=10)MixColumns(state);74 AddRoundKey(state,w[i]);75 }7677for(r=0; r<4; r++)78 {79for(c=0; c<4 ;c++)80 {81 input[c*4+r] = state[r][c];82 }83 }8485return input;86 }8788 unsigned char* AES::InvCipher(unsigned char* input)89 {90 unsigned char state[4][4];91int i,r,c;9293for(r=0; r<4; r++)94 {95for(c=0; c<4 ;c++)96 {97 state[r][c] = input[c*4+r];98 }99 }100101 AddRoundKey(state, w[10]);102for(i=9; i>=0; i--)103 {104 InvShiftRows(state);105 InvSubBytes(state);106 AddRoundKey(state, w[i]);107if(i)108 {109 InvMixColumns(state);110 }111 }112113for(r=0; r<4; r++)114 {115for(c=0; c<4 ;c++)116 {117 input[c*4+r] = state[r][c];118 }119 }120121return input;122 }123124void* AES::Cipher(void* input, int length)125 {126 unsigned char* in = (unsigned char*) input;127int i;128if(!length) // 如果是0则当做字符串处理129 {130while(*(in+length++));131in = (unsigned char*) input;132 }133for(i=0; i<length; i+=16)134 {135 Cipher(in+i);136 }137return input;139140void* AES::InvCipher(void* input, int length)141 {142 unsigned char* in = (unsigned char*) input;143int i;144for(i=0; i<length; i+=16)145 {146 InvCipher(in+i);147 }148return input;149 }150151void AES::KeyExpansion(unsigned char* key, unsigned char w[][4][4])152 {153int i,j,r,c;154 unsigned char rc[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; 155for(r=0; r<4; r++)156 {157for(c=0; c<4; c++)158 {159 w[0][r][c] = key[r+c*4];160 }161 }162for(i=1; i<=10; i++)163 {164for(j=0; j<4; j++)165 {166 unsigned char t[4];167for(r=0; r<4; r++)168 {169 t[r] = j ? w[i][r][j-1] : w[i-1][r][3];170 }171if(j == 0)172 {173 unsigned char temp = t[0];174for(r=0; r<3; r++)175 {176 t[r] = Sbox[t[(r+1)%4]];177 }178 t[3] = Sbox[temp];179 t[0] ^= rc[i-1];180 }181for(r=0; r<4; r++)182 {183 w[i][r][j] = w[i-1][r][j] ^ t[r];184 }185 }186 }187 }188189 unsigned char AES::FFmul(unsigned char a, unsigned char b)190 {191 unsigned char bw[4];192 unsigned char res=0;193int i;194 bw[0] = b;195for(i=1; i<4; i++)196 {197 bw[i] = bw[i-1]<<1;198if(bw[i-1]&0x80)199 {200 bw[i]^=0x1b;201 }202 }203for(i=0; i<4; i++)204 {205if((a>>i)&0x01)206 {207 res ^= bw[i];208 }209 }210return res;211 }212213void AES::SubBytes(unsigned char state[][4])214 {215int r,c;216for(r=0; r<4; r++)217 {218for(c=0; c<4; c++)219 {220 state[r][c] = Sbox[state[r][c]];221 }222 }223 }224225void AES::ShiftRows(unsigned char state[][4])226 {227 unsigned char t[4];228int r,c;229for(r=1; r<4; r++)230 {231for(c=0; c<4; c++)232 {233 t[c] = state[r][(c+r)%4];234 }235for(c=0; c<4; c++)236 {237 state[r][c] = t[c];238 }239 }240 }241242void AES::MixColumns(unsigned char state[][4])243 {244 unsigned char t[4];245int r,c;246for(c=0; c< 4; c++)247 {248for(r=0; r<4; r++)249 {250 t[r] = state[r][c];251 }252for(r=0; r<4; r++)253 {254 state[r][c] = FFmul(0x02, t[r])255 ^ FFmul(0x03, t[(r+1)%4])256 ^ FFmul(0x01, t[(r+2)%4])257 ^ FFmul(0x01, t[(r+3)%4]);258 }259 }260 }261262void AES::AddRoundKey(unsigned char state[][4], unsigned char k[][4]) 263 {264int r,c;265for(c=0; c<4; c++)266 {267for(r=0; r<4; r++)268 {269 state[r][c] ^= k[r][c];270 }271 }272 }273274void AES::InvSubBytes(unsigned char state[][4])275 {276int r,c;277for(r=0; r<4; r++)278 {279for(c=0; c<4; c++)280 {281 state[r][c] = InvSbox[state[r][c]];282 }283 }284 }285286void AES::InvShiftRows(unsigned char state[][4])287 {288 unsigned char t[4];289int r,c;290for(r=1; r<4; r++)291 {292for(c=0; c<4; c++)293 {294 t[c] = state[r][(c-r+4)%4];295 }296for(c=0; c<4; c++)297 {298 state[r][c] = t[c];299 }300 }301 }302303void AES::InvMixColumns(unsigned char state[][4])304 {305 unsigned char t[4];306int r,c;307for(c=0; c< 4; c++)308 {309for(r=0; r<4; r++)310 {311 t[r] = state[r][c];312 }313for(r=0; r<4; r++)314 {315 state[r][c] = FFmul(0x0e, t[r])316 ^ FFmul(0x0b, t[(r+1)%4])317 ^ FFmul(0x0d, t[(r+2)%4])318 ^ FFmul(0x09, t[(r+3)%4]);319 }320 }321 }View Code 上⾯的加密算法是没问题的,但是接⼝有两个需要注意的地⽅,也就是在头⽂件中备注的地⽅:1、数组的⼤⼩必须是16字节或者16的整数倍。

C语言实现AES加密解密

C语言实现AES加密解密

C语言实现AES加密解密AES(Advanced Encryption Standard)是一种对称加密算法,它是目前广泛使用的加密标准之一、本文将介绍如何使用C语言实现AES加密和解密。

AES算法使用128位(16字节)的块进行加密和解密。

它支持128位、192位和256位长度的密钥。

在下面的示例中,我们将演示如何使用128位的密钥进行AES加密和解密。

首先,我们需要准备一个AES加密所需的密钥。

我们可以通过一个字符串来表示密钥,然后将其转换为字节数组。

在C语言中,可以使用`strncpy`函数将字符串复制到字节数组中。

```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <openssl/aes.h>#define AES_KEY_SIZE 128int mai//准备AES密钥unsigned char key[AES_KEY_SIZE/8];strncpy((char*)key, keyStr, AES_KEY_SIZE/8);//创建AES加密上下文AES_KEY aesKey;AES_set_encrypt_key(key, AES_KEY_SIZE, &aesKey); //待加密的数据unsigned char input[] = "Hello, AES!";int inputLen = sizeof(input)/sizeof(input[0]); //加密数据unsigned char encrypted[AES_BLOCK_SIZE];AES_encrypt(input, encrypted, &aesKey);//输出加密结果printf("Encrypted: ");for (int i = 0; i < AES_BLOCK_SIZE; i++)printf("%02x", encrypted[i]);}printf("\n");//创建AES解密上下文AES_set_decrypt_key(key, AES_KEY_SIZE, &aesKey); //解密数据unsigned char decrypted[AES_BLOCK_SIZE];AES_decrypt(encrypted, decrypted, &aesKey);//输出解密结果printf("Decrypted: ");for (int i = 0; i < AES_BLOCK_SIZE; i++)printf("%c", decrypted[i]);}printf("\n");return 0;```在上面的示例中,我们使用OpenSSL库提供的AES函数来执行加密和解密操作。

用C#实现AES加密和解密

用C#实现AES加密和解密

⽤C#实现AES加密和解密AES 是⼀个新的可以⽤于保护电⼦数据的加密算法。

明确地说,AES 是⼀个迭代的、对称密钥分组的密码,它可以使⽤128、192 和 256位密钥,并且⽤ 128 位(16字节)分组加密和解密数据。

与公共密钥密码使⽤密钥对不同,对称密钥密码使⽤相同的密钥加密和解密数据。

通过分组密码返回的加密数据的位数与输⼊数据相同。

迭代加密使⽤⼀个循环结构,在该循环中重复置换(permutations )和替换(substitutions)输⼊数据。

需要加⼊引⽤ using System.Security.Cryptography;///<summary>///有密码的AES加密///</summary>///<param name="text">加密字符</param>///<param name="password">加密的密码</param>///<param name="iv">密钥</param>///<returns></returns>public static string AESEncrypt(string text, string password, string iv){RijndaelManaged rijndaelCipher = new RijndaelManaged();rijndaelCipher.Mode = CipherMode.CBC;rijndaelCipher.Padding = PaddingMode.PKCS7;rijndaelCipher.KeySize = 128;rijndaelCipher.BlockSize = 128;byte[] pwdBytes = System.Text.Encoding.UTF8.GetBytes(password);byte[] keyBytes = new byte[16];int len = pwdBytes.Length;if (len > keyBytes.Length) len = keyBytes.Length;System.Array.Copy(pwdBytes, keyBytes, len);rijndaelCipher.Key = keyBytes;byte[] ivBytes = System.Text.Encoding.UTF8.GetBytes(iv);rijndaelCipher.IV = ivBytes;ICryptoTransform transform = rijndaelCipher.CreateEncryptor();byte[] plainText = Encoding.UTF8.GetBytes(text);byte[] cipherBytes = transform.TransformFinalBlock(plainText, 0, plainText.Length);return Convert.ToBase64String(cipherBytes);}///<summary>///随机⽣成密钥///</summary>///<returns></returns>public static string GetIv(int n){char[] arrChar = new char[]{'a','b','d','c','e','f','g','h','i','j','k','l','m','n','p','r','q','s','t','u','v','w','z','y','x','0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','Q','P','R','T','S','V','U','W','X','Y','Z'};StringBuilder num = new StringBuilder();Random rnd = new Random(lisecond);for (int i = 0; i < n; i++){num.Append(arrChar[rnd.Next(0, arrChar.Length)].ToString());}return num.ToString();}///<summary>/// AES解密///</summary>///<param name="text"></param>///<param name="password"></param>///<param name="iv"></param>///<returns></returns>public static string AESDecrypt(string text, string password, string iv){RijndaelManaged rijndaelCipher = new RijndaelManaged();rijndaelCipher.Mode = CipherMode.CBC;rijndaelCipher.Padding = PaddingMode.PKCS7;rijndaelCipher.KeySize = 128;rijndaelCipher.BlockSize = 128;byte[] encryptedData = Convert.FromBase64String(text);byte[] pwdBytes = System.Text.Encoding.UTF8.GetBytes(password);byte[] keyBytes = new byte[16];int len = pwdBytes.Length;if (len > keyBytes.Length) len = keyBytes.Length;System.Array.Copy(pwdBytes, keyBytes, len);rijndaelCipher.Key = keyBytes;byte[] ivBytes = System.Text.Encoding.UTF8.GetBytes(iv);rijndaelCipher.IV = ivBytes;ICryptoTransform transform = rijndaelCipher.CreateDecryptor();byte[] plainText = transform.TransformFinalBlock(encryptedData, 0, encryptedData.Length);return Encoding.UTF8.GetString(plainText);}。

AES原理及其在c语言上的实现

AES原理及其在c语言上的实现

AES加密解密算法及其在c语言上的实现引言对称密码算法主要用于保证数据的机密性,通信双方在加密/ 解密过程中使用它们共享的单一密钥。

对称密码算法的使用相当广泛,密码学界已经对它们进行了深入的研究[1] 。

最常用的对称密码算法是数据加密标准(DES) 算法,它是由IBM在美国国家安全局(NSA) 授意之下研制的一种使用56 位密钥的分组密码算法。

自1977 年公布成为美国政府的商用加密标准以来已使用20 多年[2] 。

DES 的主要问题是其密钥长度较短,已不适合于当今分布式开放网络对数据加密安全性的要求。

在DES 每隔五年的评估会议中,最后一次在1998 年美国政府终于决定不再继续延用DES作为联邦加密标准,也就表明了DES 将退出加密标准的舞台,而新的标准AES(AdvancedEncryptionStandard ) 将粉墨登场[3] 。

AES是美国国家标准技术研究所NIST旨在取代DES的新一代的加密标准[3~5] 。

NIST对AES候选算法的基本要求是:对称分组密码体制;密钥长度支持128,192,256位;明文分组长度128 位;算法应易于各种硬件和软件实现。

1998年NIST开始AES第一轮征集、分析、测试,共产生了15 个候选算法。

1999 年3 月完成了第二轮AES 的分析、测试。

1999 年8 月NIST公布了五种算法(MARS,RC6,Rijndael,Serpent,Twofish) 成为候选算法。

最后,Rijn2dael[5] ,这个由比利时人设计的算法与其它候选算法在成为高级加密标准(AES) 的竞争中取得成功,于2000 年10月被NIST宣布成为取代DES的新一代的数据加密标准,即AES。

尽管人们对AES还有不同的看法[6~8] ,但总体来说,Rijndael作为新一代的数据加密标准汇聚了强安全性、高性能、高效率、易用和灵活等优点。

AES设计有三个密钥长度:128,192,256 比特, 相对而言,AES 的128 比特密钥比DES的56 比特密钥强1021倍[4] 。

C#实现AES加解密方法

C#实现AES加解密方法

C#实现AES加解密⽅法using System;using System.Collections.Generic;using System.Text;using System.Security.Cryptography;using System.IO;namespace Csharp{class AESHelper{///<summary>/// AES加密///</summary>///<param name="Data">被加密的明⽂</param>///<param name="Key">密钥</param>///<param name="Vector">向量</param>///<returns>密⽂</returns>public static String AESEncrypt(String Data, String Key, String Vector){Byte[] plainBytes = Encoding.UTF8.GetBytes(Data);Byte[] bKey = new Byte[32];Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);Byte[] bVector = new Byte[16];Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length);Byte[] Cryptograph = null; // 加密后的密⽂Rijndael Aes = Rijndael.Create();try{// 开辟⼀块内存流using (MemoryStream Memory = new MemoryStream()){// 把内存流对象包装成加密流对象using (CryptoStream Encryptor = new CryptoStream(Memory,Aes.CreateEncryptor(bKey, bVector),CryptoStreamMode.Write)){// 明⽂数据写⼊加密流Encryptor.Write(plainBytes, 0, plainBytes.Length);Encryptor.FlushFinalBlock();Cryptograph = Memory.ToArray();}}}catch{Cryptograph = null;}return Convert.ToBase64String(Cryptograph);}///<summary>/// AES解密///</summary>///<param name="Data">被解密的密⽂</param>///<param name="Key">密钥</param>///<param name="Vector">向量</param>///<returns>明⽂</returns>public static String AESDecrypt(String Data, String Key, String Vector){Byte[] encryptedBytes = Convert.FromBase64String(Data);Byte[] bKey = new Byte[32];Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);Byte[] bVector = new Byte[16];Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length);Byte[] original = null; // 解密后的明⽂Rijndael Aes = Rijndael.Create();try{// 开辟⼀块内存流,存储密⽂using (MemoryStream Memory = new MemoryStream(encryptedBytes)){// 把内存流对象包装成加密流对象using (CryptoStream Decryptor = new CryptoStream(Memory,Aes.CreateDecryptor(bKey, bVector),CryptoStreamMode.Read)){// 明⽂存储区using (MemoryStream originalMemory = new MemoryStream()){Byte[] Buffer = new Byte[1024];Int32 readBytes = 0;while ((readBytes = Decryptor.Read(Buffer, 0, Buffer.Length)) > 0){originalMemory.Write(Buffer, 0, readBytes);}original = originalMemory.ToArray();}}}}catch{original = null;}return Encoding.UTF8.GetString(original);}///<summary>/// AES加密(⽆向量)///</summary>///<param name="plainBytes">被加密的明⽂</param>///<param name="key">密钥</param>///<returns>密⽂</returns>public static string AESEncrypt(String Data, String Key){MemoryStream mStream = new MemoryStream();RijndaelManaged aes = new RijndaelManaged();byte[] plainBytes = Encoding.UTF8.GetBytes(Data);Byte[] bKey = new Byte[32];Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);aes.Mode = CipherMode.ECB;aes.Padding = PaddingMode.PKCS7;aes.KeySize = 128;//aes.Key = _key;aes.Key = bKey;//aes.IV = _iV;CryptoStream cryptoStream = new CryptoStream(mStream, aes.CreateEncryptor(), CryptoStreamMode.Write);try{cryptoStream.Write(plainBytes, 0, plainBytes.Length);cryptoStream.FlushFinalBlock();return Convert.ToBase64String(mStream.ToArray());}finally{cryptoStream.Close();mStream.Close();aes.Clear();}}///<summary>/// AES解密(⽆向量)///</summary>///<param name="encryptedBytes">被加密的明⽂</param>///<param name="key">密钥</param>///<returns>明⽂</returns>public static string AESDecrypt(String Data, String Key){Byte[] encryptedBytes = Convert.FromBase64String(Data);Byte[] bKey = new Byte[32];Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);MemoryStream mStream = new MemoryStream(encryptedBytes);//mStream.Write( encryptedBytes, 0, encryptedBytes.Length );//mStream.Seek( 0, SeekOrigin.Begin );RijndaelManaged aes = new RijndaelManaged();aes.Mode = CipherMode.ECB;aes.Padding = PaddingMode.PKCS7;aes.KeySize = 128;aes.Key = bKey;//aes.IV = _iV;CryptoStream cryptoStream = new CryptoStream(mStream, aes.CreateDecryptor(), CryptoStreamMode.Read);try{byte[] tmp = new byte[encryptedBytes.Length + 32];int len = cryptoStream.Read(tmp, 0, encryptedBytes.Length + 32);byte[] ret = new byte[len];Array.Copy(tmp, 0, ret, 0, len);return Encoding.UTF8.GetString(ret);}finally{cryptoStream.Close();mStream.Close();aes.Clear();}}}}。

C#_-AES加密+解密

C#_-AES加密+解密

{ using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(),
CryptoStreamMode.Read)) { cs.Read(decryptBytes, 0, decryptse(); }
} }
/// <summary> /// AES 解密 /// </summary> /// <param name="inputdata">输入的数据</param> /// <param name="iv">向量 128</param> /// <param name="strKey">key</param> /// <returns></returns> public static byte[] AESDecrypt(byte[] inputdata, byte[] iv, string strKey) {
} return decryptBytes; }
SymmetricAlgorithm des = Rijndael.Create(); des.Key = Encoding.UTF8.GetBytes(strKey.Substring(0, 32)); des.IV = iv; byte[] decryptBytes = new byte[inputdata.Length]; using (MemoryStream ms = new MemoryStream(inputdata))
CryptoStreamMode.Write)) { cs.Write(inputByteArray, 0, inputByteArray.Length); cs.FlushFinalBlock(); byte[] cipherBytes = ms.ToArray();//得到加密后的字节数组 cs.Close(); ms.Close(); return cipherBytes; }
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档