当前位置:首页 > 代码 > 正文

c语言aes解密代码(aes加密代码)

admin 发布:2022-12-19 20:17 181


本篇文章给大家谈谈c语言aes解密代码,以及aes加密代码对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

求纯C语言的加密解密算法编码(AES、DES。。。。。。)

请选择参考资料的网页

BeeCrypt 是一个包含高度优化的C语言加密库,包括MD5,SHA-等多种加密解密算法,该库是通用函数库,并与任何版权无关。符合GNU开放源码要求

点击下列连接可以直接下载源代码

求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位加解密。没有使用占内存很多的查表法。故运算速度会稍慢。

【密码学】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)的标准一样

谁能给我一个C语言写的AES CBC加解密源码

#include string.h

#include stdio.h

#include stdlib.h

#include openssl/aes.h

#include "encode.h"

int encode(char *content,int way)

{

AES_KEY aes;

unsigned char key[AES_BLOCK_SIZE];

unsigned char iv[AES_BLOCK_SIZE];

unsigned char *encrypt_string;

unsigned char *input_string;

int len,i;

/*Set Input string*/

if((strlen(content)+1)%AES_BLOCK_SIZE==0)

len=strlen(content)+1;

else

len=((strlen(content)+1)/AES_BLOCK_SIZE+1)*AES_BLOCK_SIZE;

input_string=(unsigned char *)calloc(len,sizeof(unsigned char));

if(input_string==NULL)

return -1;

strncpy(input_string,content,strlen(content));

for(i=0;i16;++i)

key[i]=i+12;

for(i=0;iAES_BLOCK_SIZE;++i)

iv[i]=i;

if(way==0)

{

if(AES_set_encrypt_key(key,128,aes)0)

return -1;

}

else

{

if(AES_set_decrypt_key(key,128,aes)0)

return -1;

}

encrypt_string=(unsigned char *)calloc(len,sizeof(unsigned char));

if(encrypt_string==NULL)

return -1;

if(way==0)

AES_cbc_encrypt(input_string,encrypt_string,len,aes,iv,AES_ENCRYPT);

else

AES_cbc_encrypt(input_string,encrypt_string,len,aes,iv,AES_DECRYPT);

strcpy(content,(char *)encrypt_string);

free(input_string);

free(encrypt_string);

return 0;

}

如何用C语言编写暴力破解压缩文件解压密码的程序

由于有一个重要的Rar文件,极需解开,首先试用了ARPC,但是解压的速度极慢,每秒只有30个左右,所以断了穷举破解的念头,却仍不死心,因为我从不崇尚穷举破解的方法,除非每秒可以跑几千万次的,我或许可以一试,所以决定研究一下Winrar 3.x密码算法,以期是否可以破解该密码。查看了网络上的资料,包括看雪FAQ里的回答,都声称只能用穷举法破解,起先并不理解,但通过研究,我理解了看雪前辈们在FAQ里所说的原因,不禁让我佩服

Winrar加密思路的成熟。虽然研究的结果没有什么新意,但我还是决定把我的研究结果与大家一起分享,为那些仍然以为winrar密码可以象破解注册码一样的,通过修改winrar弹出框之类的更改文件流程指向可以达到跳过密码检验的朋友,做一个简要的说明。

一、Rar文件生成的流程。

Winrar加密文件时,总的分两个步骤:

 1:先把源文件压缩,压成一段数据段。

 2:再将压缩完的数据段加密。

对于同一个源文件来说,不进行加密,压缩完,其rar文件中的数据段是一模一样的。但是如果对同一个源文件来说,即使使用同一个密码,加密完rar文件中的数据段是不一样的,这是由于加密的密钥是依赖于一个Salt(8个字节的密钥,用来加密时使用,存放在rar文件头中里)

所以要解密rar加密文件关键在于数据解密这一步,那我们接下来研究一下如何加密的。

二、加密“压缩完的数据段”的流程

1、获取密钥:

将明文的密码与Salt一起,通过HASH算法,生成两个16字节的密钥。(一个是KEY(AES算法的参数),一个是initVector)

2、以Key和initVector来加密压缩数据:

这里,是一个循环加密的结构,每16字节作为一个块,进行加密(这可能正是为什么加密完的文件长度总为16倍数的原因)。加密采用AES算法(RAR采用的是AES的rijndael的标准应用)。这里注意:AES加密前,有一个异或运算,是先将每16字节块与上一个16字节块加密结果进行异或,然后再进行AES算法的。我用一个简单的示意代码看说明:

;===============================================

packblock[0]=packblock[i]^initVector

encryptBlock[0]=AES(packblock[0])  ;(KEY为AES的密钥)

for i=1 to 块数量-1

packblock[i]=packblock[i]^encryptBlock[i-1]

encryptBlock[i]=AES(packblock[i]) ;(KEY为AES的密钥)

next

;packblock[i]表示压缩完的每16字节数据

  ;encryptBlock[i]表示加密完的每16字节数据

;===============================================

三、解密的过程

由于AES算法是对称的,所以解密的过程,是加密过程的逆运算。但解密时AES算法过程与加密所用的不一样(是因为解密过程中由KEY生成的子密钥表不一样)。仍然需要我们将密码输入,与salt一起生成两个16字节密钥,KEY和initVector。

;===============================================

packblock[0]=AES1(encryptBlock[0])  ;(KEY为AES的密钥)

packblock[0]=packblock[i]^initVector

for i=1 to 块数量-1

packblock[i]=AES1(encryptBlock[i])  ;(KEY为AES的密钥)

  packblock[i]=packblock[i]^encryptBlock[i-1]

next

;===============================================

那判断密码是否正确的在什么地方呢?

解密的过程是解密后的数据块进行解压缩,然后解成源文件,对该文件进行CRC校验,存在RAR文件中的源文件CRC校验码比较,相同则密码正确,不相同则密码错误。

四、无法秒破的原因

从上面,我们了解了RAR文件的整体思路。地球人都知道,解密时,肯定有个步骤是来判断密码的正确与否。而且,依据以往的经验,我们也许可以将某些判断的点移动,那样可以缩减破解的流程思路。那RAR的这一步在哪里?它把校验放在了最后的一步。如果要秒破,我们该怎么做泥?至少我认为目前是不可能的。

我们从解密过程逆反过来看看:

1、CRC检验这一块修改跳转?根本毫无意义,因为它已经是最后一步了。你可以修改RAR文件头的CRC值,你可以将它改得和你用任意密码解压出来的文件CRC值一样,但你的文件根本就不是原来的文件了。可能已经完全面目全非了。所以,对这一过程不可行。CRC校验本身是不可逆的

2、那么把判断提前到压缩完的数据?

解压的时候,有没有什么来判断压缩数据是否正确?压缩完的数据,有没有固定的特征,是否可以做为解压的判断,在这一步里,我们也无法找到有效的可用的固定特征。因为这一步涉及到RAR的压缩算法。即使一个源文件,即使你的文件前一部分是完全相同的,只对后面的部分进行改过,那么压缩完,数据也是完全一样的。因为压缩完的数据首先是一个压缩表,后面是编码。文件不一样,扫描完的压缩表也不一样,编码又是依赖于压缩表,所以,这里头找不到压缩完的数据有任何的固定特征可以用来判断的。

不管压缩数据是什么样的,Winrar都一如既往地进行解压,没有进行压缩数据是否有效的判断。

3、那假如我们破解了AES了泥?

由于AES只依赖于KEY,如果AES算法被破解了,我们知道了KEY,我们可以解出压缩完的数据,但是这里有一个问题,还有一个initVector密钥,用来第一个16字节块的异或,你没有initVector参数,你第一个16字节块的数据便无法解得出来。

4、那就只能从第一步Hash的算法入手

即使你能破解hash,但hash后的结果泥?没有结果,你怎么返推密码。

所以综上,我发现rar的加密是由hash和AES两种算法互相牵制,而两种算法当前都无法破解,至少目前还没有办法秒破,也理解了看雪高手讲的道理。

五、对穷举提高算法效率的一些设想。

我用汇编写完了RAR穷举解密的算法模块,但是如何提高效率,优化穷举的速度泥?我有如下的想法:

1、从压缩数据里找寻特征,省掉解压缩、CRC检验代码和生成initVector生成代码。目前,通过多次实验,我找到的一个特征(不知道这个是否正确),即解密完的最后一个16字节块的最后一个字节必须为0。因为经过多次的试验,我发现有加密的数据段长度都会比未加密前的数据长,那么,最后一个

16个字节的数据块解密完,多出的部分就都为0,但多出几个字节泥?多次实验,长度不一,我试想着从加密数据段最后一个16个字节块着手,只解这一块,看是否一个字节为0,这样,只解密16个字节的数据,来大大提高效率?如果能进行到这一步了,再通过解全部数据,进行CRC校验的判断。

2、如果第一个特征不成立的话,针对特定格式的压缩文件,比如doc、jpg等,部分数据固定,压缩完的数据是否存在相互牵制的数据?从而把判断提前,这一步,我不知道如何找到压缩完的数据是否存在相互牵制的数据。

关于c语言aes解密代码和aes加密代码的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

版权说明:如非注明,本站文章均为 AH站长 原创,转载请注明出处和附带本文链接;

本文地址:http://ahzz.com.cn/post/22520.html


取消回复欢迎 发表评论:

分享到

温馨提示

下载成功了么?或者链接失效了?

联系我们反馈

立即下载