这个本来是专门用来加密ASCII码文的,号称是二战时德国鬼子用来加密机密军事文件的。
我变通着扩展它的码表后,可以以字节为单位用来加密任何文件。
解密也很简单,是加密的逆过程,算法完全一样。
编译后实际运行了一下,速度还算不错,和WinRAR压缩速度相比,同体积的文件大概慢了50%左右吧。
不过我不太清楚这种算法的强度如何,下面贴出我的VC源码片断(dll 工程),请高手研究一下,到底怎样,有没有实用性。
#include "memory.h"
#include "stdlib.h"
#include "string.h"
unsigned char MatrixTable[256][256];
unsigned char *SecretKeyArray;
unsigned long SecretKeyLength;
unsigned long __stdcall SetSecretKey(LPCSTR lpSecretKey)
{
if(SecretKeyArray != NULL)
free(SecretKeyArray);
SecretKeyLength = strlen(lpSecretKey);
SecretKeyArray = (unsigned char *)malloc(SecretKeyLength);
memcpy(SecretKeyArray, lpSecretKey, SecretKeyLength);
return SecretKeyLength;
}
void __stdcall SetMatrixTable(unsigned char *pBuffer)
{
long i, j;
memcpy(MatrixTable + 0, pBuffer, 256);
for(i = 1; i < 256; i++)
{
for(j = 1; j < 256; j++)
MatrixTable[i][j - 1] = MatrixTable[i - 1][j];
MatrixTable[i][255] = MatrixTable[i - 1][0];
}
}
void __stdcall EncryptRoutine(unsigned char *pBuffer,
unsigned long nLength,
bool fSetSKStart,
unsigned long *nCounter)
{
unsigned char byData;
static unsigned long pSKWalk;
long i, j, k;
if(SecretKeyArray == NULL || SecretKeyLength == 0)
return;
if(fSetSKStart)
pSKWalk = 0;
for(i = 0; i < nLength; i++)
{
byData = *(pBuffer + i);
for(j = 0; j < 256; j++)
{
if(MatrixTable[0][j] == byData)
break;
}
byData = *(SecretKeyArray + pSKWalk);
for(k = 0; k < 256; k++)
{
if(MatrixTable[k][j] == byData)
{
*(pBuffer + i) = MatrixTable[k][0];
break;
}
}
pSKWalk++;
if(pSKWalk >= SecretKeyLength)
pSKWalk = 0;
if(nCounter != NULL)
(*nCounter)++;
}
}
以上。
应用时先调用SetSecretKey函数设置密钥,因为最终是按字节读取密钥的,因此可接受任何字符。长度不限。
接着调用SetMatrixTable函数初始化256*256的码表,参数pBuffer传入一个预先生成的256Byte的原始码表首地址。这个原始码表在加密前由程序随机生成,亦可从密文文件中读入。内容是0~255共256个乱序值,不同的排列顺序和密钥共同决定了加密文件的唯一性。
之后就可以调用EncryptRoutine来加密了。解密过程与加密过程完全相同,亦是调用此函数。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)