aes加密c代码(AES加解密C语言实现)
admin 发布:2022-12-19 19:42 220
今天给各位分享aes加密c代码的知识,其中也会对AES加解密C语言实现进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
谁知道哪里有AES算法加密,解密c++/C语言代码?
我有写好的,肿么给你?贴上来吧。
#ifndef aes_h_
#define aes_h_
#include iostream
#include string
using namespace std;
typedef unsigned char uint8;
class aes
{
public:
/// 构造函数
aes();
/// 析构函数
~aes();
/// 加密,默认256位密码
///
/// @param input 要加密的字符串
/// @param output 加密后字符串
/// @return 无
/// @see
/// @note (note描述需要注意的问题)
void encrypt(const string input, string output);
/// 解密 默认密码
///
/// @param input 要解密字符串
/// @param output 解密后字符串
/// @return 无
/// @see
/// @note (note描述需要注意的问题)
void decrypt(const string input, string output);
/// 加密 256位
///
/// @param key 密码
/// @param input 要加密的字符串
/// @param output 加密后字符串
/// @return 无
/// @see
/// @note (note描述需要注意的问题)
void encrypt(uint8 key[32], const string input, string output);
/// 解密 256位
///
/// @param key 密码
/// @param input 要解密字符串
/// @param output 解密后字符串
/// @return 无
/// @see
/// @note (note描述需要注意的问题)
void decrypt(uint8 key[32],const string input, string output);
private:
typedef struct
{
uint32 erk[64]; /* encryption round keys */
uint32 drk[64]; /* decryption round keys */
int nr; /* number of rounds */
}aes_context;
int aes_set_key( aes_context* ctx, uint8* key, int nbits );
void aes_encrypt( aes_context* ctx, uint8 input[16], uint8 output[16] );
void aes_decrypt( aes_context* ctx, uint8 input[16], uint8 output[16] );
};
#endif // aes_h_
我晕,太长贴不上来啊?
【密码学】C语言实现AES核心步骤
按照AES算法,完成AES算法S盒、行移位、列混合、轮密钥加操作
高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。
AES采用对称分组密码体制,密钥的长度最少支持为128、192、256,分组长度128位,算法应易于各种硬件和软件实现。
AES加密数据块分组长度必须为128比特,密钥长度可以是128比特、192比特、256比特中的任意一个(如果数据块及密钥长度不足时,会补齐)。AES加密有很多轮的重复和变换。大致步骤如下:1、密钥扩展(KeyExpansion),2、初始轮(Initial Round),3、重复轮(Rounds),每一轮又包括:字节替代(SubBytes)、行移位(ShiftRows)、列混合(MixColumns)、轮密钥加(AddRoundKey),4、最终轮(Final Round),最终轮没有MixColumns。
AES算法的加密整体结构
字节替代(SubBytes):使用一个S盒进行非线性置换,S盒是一个16×16的矩阵,如表4-9所示。字节替代将输入的状态矩阵的每一个字节通过一个简单查表操作,映射为另外一个字节。
输入字节的前4bits指定S盒的行值,后4bits指定S盒的列值,行和列所确定S盒位置的元素作为输出,例如输入字节“03”,行值为0,列值为3,根据表4-9可知第0行第3列对应的值为 “7B”,因此输出字节为“7B”。
举例
在上面的示例中,第1个基本元素为”F5”,它将被S盒行为第”F行”、列为第”5”列的元素“E6“代替,其余的输出也用相同的方法确定。
状态阵列的4个行循环以字节为基本单位进行左移,而每行循环做移的偏移量是由明文分组的大小和所在行数共同确定,即列数Nb和行号确定。
举例
举例
轮密钥加操作是将密钥与明文按比特异或,轮密钥通过密钥扩展得到
和fips-192(AES)的标准一样
求AES加密算法 C代码
以前编过的,c++可以用的
#include iostream
using namespace std;
long gcd(long a, long b)
{
if(ba) //a中存放较大的数,b中存放较小的数
{
int temp;
temp=a;
a=b;
b=temp;
}
long n;
while((n=a%b)!=0)
{
a=b;
b=n;
}
return b;
}
//---------------------------------------
long cheng_niyuan(long a, long b)
{
for(long i=1; (i*a)%b!=1; i++);
return i;
}
//---------------------------------------
int mi_mo(int a, int b, int n)
{
int K[100];
int top=-1;
while(b)
{
top++;
K[top]=(b%2);
b/=2;
}
int c=0, f=1;
for(; top=0; top--)
{
c=2*c;
f=(f*f)%n;
if(K[top]==1)
{
c+=1;
f=(f*a)%n;
}
}
return f;
}
//---------------------------------------
int main()
{
int p=5,q=11;
cout"p="pendl;
cout"q="qendl;
long int n=p*q;
cout"n="nendl;
long int fi_n=(p-1)*(q-1);
cout"fi_n="fi_nendl;
int e=3;
cout"e="eendl;
long d=cheng_niyuan(e,fi_n);
int M, C;
cout"请输入明文:"endl;
cinM;
C=mi_mo(M, e, n);
cout"对应的密文为:"endl;
coutCendl;
cout"请输入密文:"endl;
cinC;
M=mi_mo(C, d, n);
cout"对应的明文为:"endl;
coutMendl;
return 0;
}
求AES算法加密C语言完整程序
恰好我有。能运行的,C语言的。
#include string.h
#include "aes.h"
#include "commonage.h"
#define byte unsigned char
#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 KEYBITS 128 //! Use AES128.
#define ROUNDS 10 //! Number of rounds.
#define KEYLENGTH 16 //! Key length in number of bytes.
byte xdata block1[ 256 ]; //! Workspace 1.
byte xdata block2[ 256 ]; //! Worksapce 2.
byte xdata * powTbl; //! Final location of exponentiation lookup table.
byte xdata * logTbl; //! Final location of logarithm lookup table.
byte xdata * sBox; //! Final location of s-box.
byte xdata * sBoxInv; //! Final location of inverse s-box.
byte xdata * expandedKey; //! Final location of expanded key.
void CalcPowLog( byte * powTbl, byte * logTbl )
{
byte xdata i = 0;
byte xdata 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( byte * sBox )
{
byte xdata i, rot;
byte xdata temp;
byte xdata 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 = (temp1) | (temp7);
// Add rotated byte in GF(2).
result ^= temp;
}
// Put result in table.
sBox[i] = result;
} while( ++i != 0 );
}
void CalcSBoxInv( byte * sBox, byte * sBoxInv )
{
byte xdata i = 0;
byte xdata j = 0;
// Iterate through all elements in sBoxInv using i.
do {
// Search through sBox using j.
cleardog();
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( byte * row )
{
// Cycle 4 bytes in an array left once.
byte xdata temp = row[0];
row[0] = row[1];
row[1] = row[2];
row[2] = row[3];
row[3] = temp;
}
void InvMixColumn( byte * column )
{
byte xdata 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;
}
byte Multiply( unsigned char num, unsigned char factor )
{
byte mask = 1;
byte 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;
}
byte DotProduct( unsigned char * vector1, unsigned char * vector2 )
{
byte result = 0;
result ^= Multiply( *vector1++, *vector2++ );
result ^= Multiply( *vector1++, *vector2++ );
result ^= Multiply( *vector1++, *vector2++ );
result ^= Multiply( *vector1 , *vector2 );
return result;
}
void MixColumn( byte * column )
{
byte xdata row[8] = {
0x02, 0x03, 0x01, 0x01,
0x02, 0x03, 0x01, 0x01
}; // Prepare first row of matrix twice, to eliminate need for cycling.
byte xdata 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 SubBytes( byte * bytes, byte count )
{
do {
*bytes = sBox[ *bytes ]; // Substitute every byte in state.
bytes++;
} while( --count );
}
void InvSubBytesAndXOR( byte * bytes, byte * key, byte 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( byte * state )
{
byte 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 ShiftRows( byte * state )
{
byte 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 InvMixColumns( byte * state )
{
InvMixColumn( state + 0*4 );
InvMixColumn( state + 1*4 );
InvMixColumn( state + 2*4 );
InvMixColumn( state + 3*4 );
}
void MixColumns( byte * state )
{
MixColumn( state + 0*4 );
MixColumn( state + 1*4 );
MixColumn( state + 2*4 );
MixColumn( state + 3*4 );
}
void XORBytes( byte * bytes1, byte * bytes2, byte count )
{
do {
*bytes1 ^= *bytes2; // Add in GF(2), ie. XOR.
bytes1++;
bytes2++;
} while( --count );
}
void CopyBytes( byte * to, byte * from, byte count )
{
do {
*to = *from;
to++;
from++;
} while( --count );
}
void KeyExpansion( byte * expandedKey )
{
byte xdata temp[4];
byte i;
byte xdata Rcon[4] = { 0x01, 0x00, 0x00, 0x00 }; // Round constant.
unsigned char xdata *key;
unsigned char xdata a[16];
key=a;
//以下为加解密密码,共16字节。可以选择任意值
key[0]=0x30;
key[1]=0x30;
key[2]=0x30;
key[3]=0x30;
key[4]=0x30;
key[5]=0x30;
key[6]=0x30;
key[7]=0x30;
key[8]=0x30;
key[9]=0x30;
key[10]=0x30;
key[11]=0x30;
key[12]=0x30;
key[13]=0x30;
key[14]=0x30;
key[15]=0x30;
////////////////////////////////////////////
// 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( byte * block, byte * expandedKey )
{
byte 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 Cipher( byte * block, byte * expandedKey ) //完成一个块(16字节,128bit)的加密
{
byte 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 aesInit( unsigned char * tempbuf )
{
powTbl = block1;
logTbl = block2;
CalcPowLog( powTbl, logTbl );
sBox = tempbuf;
CalcSBox( sBox );
expandedKey = block1; //至此block1用来存贮密码表
KeyExpansion( expandedKey );
sBoxInv = block2; // Must be block2. block2至此开始只用来存贮SBOXINV
CalcSBoxInv( sBox, sBoxInv );
}
//对一个16字节块解密,参数buffer是解密密缓存,chainBlock是要解密的块
void aesDecrypt( unsigned char * buffer, unsigned char * chainBlock )
{
//byte xdata temp[ BLOCKSIZE ];
//CopyBytes( temp, buffer, BLOCKSIZE );
CopyBytes(buffer,chainBlock,BLOCKSIZE);
InvCipher( buffer, expandedKey );
//XORBytes( buffer, chainBlock, BLOCKSIZE );
CopyBytes( chainBlock, buffer, BLOCKSIZE );
}
//对一个16字节块完成加密,参数buffer是加密缓存,chainBlock是要加密的块
void aesEncrypt( unsigned char * buffer, unsigned char * chainBlock )
{
CopyBytes( buffer, chainBlock, BLOCKSIZE );
//XORBytes( buffer, chainBlock, BLOCKSIZE );
Cipher( buffer, expandedKey );
CopyBytes( chainBlock, buffer, BLOCKSIZE );
}
//加解密函数,参数为加解密标志,要加解密的数据缓存起始指针,要加解密的数据长度(如果解密运算,必须是16的整数倍。)
unsigned char aesBlockDecrypt(bit Direct,unsigned char *ChiperDataBuf,unsigned char DataLen)
{
unsigned char xdata i;
unsigned char xdata Blocks;
unsigned char xdata sBoxbuf[256];
unsigned char xdata tempbuf[16];
unsigned long int xdata OrignLen=0; //未加密数据的原始长度
if(Direct==0)
{
*((unsigned char *)OrignLen+3)=ChiperDataBuf[0];
*((unsigned char *)OrignLen+2)=ChiperDataBuf[1];
*((unsigned char *)OrignLen+1)=ChiperDataBuf[2];
*((unsigned char *)OrignLen)=ChiperDataBuf[3];
DataLen=DataLen-4;
}
else
{
memmove(ChiperDataBuf+4,ChiperDataBuf,DataLen);
OrignLen=DataLen;
ChiperDataBuf[0]=OrignLen;
ChiperDataBuf[1]=OrignLen8;
ChiperDataBuf[2]=OrignLen16;
ChiperDataBuf[3]=OrignLen24;
}
cleardog();
aesInit(sBoxbuf); //初始化
if(Direct==0) //解密
{
Blocks=DataLen/16;
for(i=0;iBlocks;i++)
{
cleardog();
aesDecrypt(tempbuf,ChiperDataBuf+4+16*i);
}
memmove(ChiperDataBuf,ChiperDataBuf+4,OrignLen);
cleardog();
return(OrignLen);
}
else //加密
{
if(DataLen%16!=0)
{
Blocks=DataLen/16+1;
//memset(ChiperDataBuf+4+Blocks*16-(DataLen%16),0x00,DataLen%16); //不足16字节的块补零处理
}
else
{
Blocks=DataLen/16;
}
for(i=0;iBlocks;i++)
{
cleardog();
aesEncrypt(tempbuf,ChiperDataBuf+4+16*i);
}
cleardog();
return(Blocks*16+4);
}
}
//#endif
以上是C文件。以下是头文件
#ifndef AES_H
#define AES_H
extern void aesInit( unsigned char * tempbuf );
extern void aesDecrypt(unsigned char *buffer, unsigned char *chainBlock);
extern void aesEncrypt( unsigned char * buffer, unsigned char * chainBlock );
extern void aesInit( unsigned char * tempbuf );
extern void aesDecrypt( unsigned char * buffer, unsigned char * chainBlock );
extern void aesEncrypt( unsigned char * buffer, unsigned char * chainBlock );
extern unsigned char aesBlockDecrypt(bit Direct,unsigned char *ChiperDataBuf,unsigned char DataLen);
#endif // AES_H
这是我根据网上程序改写的。只支持128位加解密。没有使用占内存很多的查表法。故运算速度会稍慢。
关于aes加密c代码和AES加解密C语言实现的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
版权说明:如非注明,本站文章均为 AH站长 原创,转载请注明出处和附带本文链接;
相关推荐
- 05-06单页网站的代码(完整的网页代码)[20240506更新]
- 05-06个人主页图片代码(个人主页图片代码怎么弄)[20240506更新]
- 05-06提取微信名片代码(微信名片信息提取)[20240506更新]
- 05-06php后台权限管理代码(php管理员权限)[20240506更新]
- 05-06付费观看代码php(付费观看代码)[20240506更新]
- 05-06在线html执行代码(html怎么运行)[20240506更新]
- 05-06源代码管理资源管理器(资源管理器运行代码)[20240506更新]
- 05-06代码源软件库(程序代码库)[20240506更新]
- 05-06点击弹出密码代码(点击弹出密码代码错误)[20240506更新]
- 05-06滚动导航代码(导航页面代码)[20240506更新]
取消回复欢迎 你 发表评论:
- 标签列表
- 最近发表
- 友情链接