我们日常工作中经常要对一些东西进行加密,可选的加密方法当然很多了,Windows都自带了加密库,但密码学方面的东西实在令我头大,可能因为我从小学开始数学一直没学好的缘故,而我仔细考虑之后发觉:我们对信息加密,不一定是出自于什么“top security”的原因,大多可能仅仅是不想让用户看到具体的文件的结构或保护一些个人隐私信息,也就是说对安全的要求一般,没必要引入太过重量级的东西,最好是非常快捷、高效和轻量的。那本文提供了一种方法,能让你的信息看起来被很好地加过密了,并且你根本不需要去研究什么密码学,也不需要引入什么庞大的Lib,因为代码就那么几行。
写这个程序的时候其实我是想要这么一种加密方法:假如明文只有一个字节,那加密出来的密文应该也只有一个字节。而实际上别人实现好的AES算法加密出来的密文通常都要带上一串随机数,不太符合我的要求。
没有什么include,没有什么LIB,更没有什么DLL,代码再简单不过,但我保证它很有效,OK,不多说了,看代码:
#include "String.h"
//加密和解密,其实这两个函数完全相同的,简单起见嘛,另外我居然允许密码为空,也是简单起见
void JiangEncode(unsigned char *pBuff, int iBuffLen, char *pKey=NULL, int iKeyLen=0);
void JiangDecode(unsigned char *pBuff, int iBuffLen, char *pKey=NULL, int iKeyLen=0);
//这个main函数是用来测试的
#define TEST_LEN 100
int main(int argc, char* argv[])
{
unsigned char totest[TEST_LEN];
memcpy(totest, "012345678901234567890123456789012345678901234567890123456789\
0123456789012345678901234567890123456789", 100);
JiangEncode(totest, TEST_LEN, "J~xye", 6);
int i;
for(i=0; i<TEST_LEN; i++)
{
if((i%10)==0)
printf("\n");
printf("%d ", totest[i]);
}
printf("\n");
JiangDecode(totest, TEST_LEN, "J~xye", 6);
for(i=0; i<TEST_LEN; i++)
{
if((i%10)==0)
printf("\n");
printf("%d ", totest[i]);
}
return 0;
}
//交换两个BYTE
void Swap2Byte(unsigned char* v1, unsigned char* v2)
{
*v1 ^= *v2;
*v2 ^= *v1;
*v1 ^= *v2;
}
void GetMyCypher(const char* pKey, int iKeyLen, unsigned char* pMyCypher)
{
//原始加密索引
const unsigned char cypherOrg[256] =
{
1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53,
95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170,
229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49,
83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205,
76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136,
131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154,
181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160,
251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65,
195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117,
159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128,
155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84,
252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202,
69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23,
57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1
};
memcpy(pMyCypher, cypherOrg, 256);
//根据密码调整加密索引
int i, j;
for(i=0; i<iKeyLen; i++)
{
for(j=0; j<256; j++)
{
int iSwitchIndex = (pMyCypher[j] * pKey[i])%255;
if(iSwitchIndex!=j)
Swap2Byte(&(pMyCypher[j]), &(pMyCypher[iSwitchIndex]));
}
}
}
void JiangCode(unsigned char* pBuff, int iBuffLen, char* pKey, int iKeyLen)
{
unsigned char cypher[256];
GetMyCypher(pKey, iKeyLen, cypher);
int iIndex=0;
while (iIndex<iBuffLen)
{
//其实……也就一个异或操作,所以加密和解密的过程完全一样
pBuff[iIndex] ^= cypher[iIndex%256];
++iIndex;
}
}
void JiangEncode(unsigned char* pBuff, int iBuffLen, char* pKey, int iKeyLen)
{
JiangCode(pBuff, iBuffLen, pKey, iKeyLen);
}
void JiangDecode(unsigned char* pBuff, int iBuffLen, char* pKey, int iKeyLen)
{
JiangCode(pBuff, iBuffLen, pKey, iKeyLen);
}
写完了,运行结果是如下:
241 206 235 249 4 160 190 73 253 196
160 238 105 243 18 190 10 97 26 66
182 218 99 73 40 204 208 123 196 46
76 208 117 159 38 66 234 117 142 52
66 63 135 193 60 49 228 15 12 58
131 252 1 171 96 72 254 198 171 201
110 242 27 189 199 108 136 12 177 215
88 66 156 183 221 142 27 45 61 221
122 158 39 174 123 112 156 241 77 227
112 148 57 67 225 30 47 49 83 94
48 49 50 51 52 53 54 55 56 57
48 49 50 51 52 53 54 55 56 57
48 49 50 51 52 53 54 55 56 57
48 49 50 51 52 53 54 55 56 57
48 49 50 51 52 53 54 55 56 57
48 49 50 51 52 53 54 55 56 57
48 49 50 51 52 53 54 55 56 57
48 49 50 51 52 53 54 55 56 57
48 49 50 51 52 53 54 55 56 57
48 49 50 51 52 53 54 55 56 57 Press any key to continue
上面这段是密文,看起来是不是完全没有原文的样子了?你试试看把TEST_LEN改为1,只加密一个字节看,这也是允许的,代码纯C,移植性很好,拿去别处用也方便。但对安全性要求高的应用可能不能使用这种方法了,至于怎么样才算安全,我也不知道,密码学方面的东西我最害怕了。