在网络传输重要信息或存储重要文件信息时,大部分会对数据加密,保证数据的安全性。互联网上流行的可逆加密方式对数据的安全性没有保证,便自己写了一套安全性极高加密、解密方法。
方法的实现方式及特点:
1.采用指定单个字节加密转换(转换形式为ascll码表中0-128的形式,由1个字节拆分为三个字节,下面说明拆分方式);
2.采用数组中随机数据减指定加密字节(比如当前数据ascll码为121,当前数组中的数据为222,结果为222-121=101,当然这个只是参考实例);
3.采用随机指定数组方式(如果需要用到无规律加密方式,可以通过随机指定数组方式进行加密);
4.指定很大的数据加密格式(比如使用1-2048字节中任意长度为一次的加密比例,大量数据分为多次加密);
5.多次加密数据时,第一次加密数据生成数据头与加密信息,之后只生成加密信息(数据头包含使用的加密数组(比如数组1、数组2、等…,)和加密字节长度,解析数据时将会根据数据头获取到这些信息);
6.加密字节为跳序形式(比如指定加密1,3,5字节或者指定为别的字节调序形式,只需简单改些代码就能实现);
指定一个字节加密后拆分为三个字节表示为:
①第一个字节为随机数组中的随机数据(比如数组有8个数据,第一个字节范围0-7作为标记,用来解密使用);
②第二个字节为加密后的数据拆分的一部分(小于128用来对上ascll码表);
③第三个字节为采用的拆分格式(解密使用)。
下面贴上加密使用的数组:
1
2
3
4
5
6
|
//数组中的任意数据都可以修改为1-255之间,末尾数据为0防止数组越界
unsigned char Data1[] ={255,210,208,179,168,199,202,189,0};
unsigned char Data2[] ={166,207,205,196,191,190,163,180,0};
unsigned char Data3[] ={155,197,186,172,228,226,219,239,0};
unsigned char Data4[] ={188,229,192,254,252,212,230,217,0};
unsigned char Data5[] ={229,206,212,224,253,211,181,207,0};
|
目前代码中使用的是这5个数组,需要更大的随机性可以通过简单修改代码,写入更多的数组,数组中的数据在1-255(不建议写0,字符串中0为结尾)。
数据头定义格式:
数据头1-3字节为“LKY”用来校验加密后的数据,如果数据中不存在,将不处理数据;
数据头4-128字节为校验信息段,如果校验不正确,将不处理数据;
数据头129-133字节为使用的指定数组进行加密(目前最大可以指定5个数组,同时使用5个数组进行对指定直接加密处理,修改代码可以增加更多的数组);
数据头134-256字节为补数据;
数据头257-260字节为指定的加密长度(加密长度为1-2048);
数据头261-512字节为补数据;
数据头的总长度为512个字节。
下面贴上.h文件(其中包括任意格式文件的加密、解密函数):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
#include <vector>
struct FileData
{
CString Filename;
LPVOID _this;
bool bCover;
};
//数据加密解密类
class DataOperation
{
public :
DataOperation();
virtual ~DataOperation();
/***************************** 加密部分 ***************************/
//设置加密数据(传入1表示使用unsigned char Data1[] ={255,210,208,179,168,199,202,189,193,0}数组加密)传入类型1-5,
//如果传入数据超过5次,不再记录
bool SetEncryptionData( int nCount);
//设备每一次加密的数据长度值为0-2048,默认使用2048
bool SetEncryptionLen( int nLen);
//加密数据函数
//返回加密完成的函数
//如果传入的数据超过设置每一次加密的数据长度,将会采用设置的数据长度
//第一次调用会生成512字节数据头与加密后的数据一起返回(比如需要加密3048个字节数据,第一次调用函数返回数据头和2048加密后的数据,第二次调用返回剩下1000个字节加密后的数据)
char *EncryptionData( char * SrcData, int & nDataLen);
//加密文件
//参数一文件完整路径加名称
//参数二 true为覆盖文件 false为创建文件名加_Temp的新文件
bool EncryptionFile(CString Filename, bool bCover);
/**********************************************/
/****************** 解密部分 *****************************/
//解析数据头信息,返回每一次解密需要传入的数据长度(使用加密后的数据前512字节为数据头信息传入函数获取到加密数据以及加密的数据长度等)
int DecryptionHead( char * SrcData);
//解密数据(传入加密后的数据以及数据长度,不要带数据头信息)
//比如解密3048字节长度数据,去掉数据512个字节数据(数据头信息),从513字节开始为需要解析的数据
//nDataLen 为解析数据头返回的每次需要传入的数据长度
char *DecryptionData( const char * SrcData, int & nDataLen);
//解密文件
bool DecryptionFile(CString Filename, bool bCover);
/************************************************/
private :
//加密数据计算函数
char *EncryptionData_( char * SrcData, int & nDataLen, char *HeadData = 0);
//指定字节进行加密运算
unsigned char *Encryption_Operation(std::vector<unsigned char *> VData,unsigned char SrcData[]);
//获取指定的加密数组
unsigned char * GetData_Operation( int nVal);
//根据指定加密长度获取解密长度
int GetDecryptionDataLen( int nDataLen);
//指定字节进行解密运算
unsigned char *Decryption_Operation(unsigned char * VData[],unsigned char SrcData[], int nVDataLen);
private :
//保存需要使用的加密数据(只在加密数据时使用,解密时自动根据数据头信息获取加密数据)
char m_EncryptionData[6];
//保存需要使用的解密数据
char m_DecryptionData[6];
//
int m_EncryptionDataLen;
//
int m_DecryptionDataLen;
//
bool m_bValidHead;
};
|
下面贴上.cpp文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
|
#include "stdafx.h"
#include "Operation.h"
unsigned char Data1[] ={255,210,208,179,168,199,202,189,0};
unsigned char Data2[] ={166,207,205,196,191,190,163,180,0};
unsigned char Data3[] ={155,197,186,172,228,226,219,239,0};
unsigned char Data4[] ={188,229,192,254,252,212,230,217,0};
unsigned char Data5[] ={229,206,212,224,253,211,181,207,0};
//数组的长度
int DataLen = 8;
//获取数组
#define GetData(nVal)\
Data##nVal;
DataOperation::DataOperation():m_EncryptionDataLen(2048),m_bValidHead( false ),m_DecryptionDataLen(0)
{
memset (m_EncryptionData,0, sizeof (m_EncryptionData));
memset (m_DecryptionData,0, sizeof (m_DecryptionData));
SetEncryptionData(2);
SetEncryptionData(1);
}
DataOperation::~DataOperation()
{
}
//如果传入数据超过5次,不再记录
bool DataOperation::SetEncryptionData( int nCount)
{
int nLen = strlen (m_EncryptionData);
if (5 <= nLen)
return false ;
m_EncryptionData[nLen] = nCount;
return true ;
}
//设备每一次加密的数据长度值为0-2048,默认使用2048
bool DataOperation::SetEncryptionLen( int nLen)
{
if (0 >= nLen || 2048 < nLen)
return false ;
m_EncryptionDataLen = nLen;
return true ;
}
//加密数据函数
char * DataOperation::EncryptionData( char * SrcData, int & nDataLen)
{
if (0 == SrcData)
return 0;
if (!m_bValidHead)
{
//首先生出数据头,然后与数据合并
char DataHead[513] = {0};
int nInIdex = strlen ( "LKY" );
memcpy (DataHead, "LKY" ,nInIdex);
//前128位校验数据头信息
for ( int i = 3;i < 128;i++)
{
DataHead[i] = ((DataHead[i - 1] + i)%128 + 1);
}
int ii = 0;
//129-133为使用的加密数据
for ( int i = 128;i < 133;i++)
{
if (0 == m_EncryptionData[ii])
{
DataHead[i] = '0' ;
}
else
{
DataHead[i] = m_EncryptionData[ii];
}
++ii;
}
//134-256为补数据
for ( int i = 133;i < 256;i++)
{
DataHead[i] = ((DataHead[i - 1] + i)%128 + 1);
}
//257-261为加密长度
char EncryptionDataLen[5] = {0};
itoa(m_EncryptionDataLen,EncryptionDataLen,10);
ii = 0;
for ( int i = 256;i < 260;i++)
{
if (0 == EncryptionDataLen[ii])
{
DataHead[i] = '99' ;
}
else
{
DataHead[i] = EncryptionDataLen[ii];
}
++ii;
}
//261-512为补数据
for ( int i = 260;i < 512;i++)
{
DataHead[i] = ((DataHead[i - 1] + i)%128 + 1);
}
m_bValidHead = true ;
return EncryptionData_(SrcData,nDataLen,DataHead);
}
return EncryptionData_(SrcData,nDataLen);
}
//加密数据计算函数
char *DataOperation::EncryptionData_( char * SrcData, int & nLen, char *HeadData)
{
char pStrData[2048 + 513 + 26] = {0};
int nIndex = 0;
if (0 != HeadData)
{
memcpy (pStrData,HeadData,512);
nIndex += 512;
}
int nOffset = 0,nLeft = 0;
int nDataLen = (m_EncryptionDataLen <= nLen ? m_EncryptionDataLen : nLen);
//获取加密数组
std::vector<unsigned char *>VData;
for ( int ilen = 0;ilen < strlen (m_EncryptionData);ilen++)
{
int nVal = m_EncryptionData[ilen];
unsigned char * DataArray = GetData_Operation(nVal);
VData.push_back(DataArray);
}
int i = 0;
//开始加密数据
for (;i < nDataLen;(i = i * 2 + 1))
{
//拷贝没有加密的数据
if (0 < i - nLeft)
{
memcpy (pStrData + nIndex,SrcData + nLeft,i - nLeft);
nIndex += i - nLeft;
}
unsigned char StrTemp[4] = {0,SrcData[i],0,0};
Encryption_Operation(VData,StrTemp);
if (128 <= StrTemp[1])
{
StrTemp[1] = StrTemp[1] - 127;
StrTemp[2] = 127;
}
else if (0 == StrTemp[1])
{
StrTemp[1] = '0' ;
StrTemp[2] = '0' ;
}
else
{
StrTemp[1] = 128 - StrTemp[1];
StrTemp[2] = '1' ;
}
//拷贝转换过的数据
memcpy (pStrData + nIndex,StrTemp, strlen (( char *)StrTemp));
nIndex += strlen (( char *)StrTemp);
nLeft = i + 1;
}
if (nLeft < nDataLen && 0 != nIndex)
{
memcpy (pStrData + nIndex,SrcData + nLeft,nDataLen - nLeft);
nIndex += nDataLen - nLeft;
}
else if (0 == nIndex)
{
nLen = nDataLen;
return pStrData;
}
nLen = nIndex;
return pStrData;
}
//指定字节进行加密运算
unsigned char *DataOperation::Encryption_Operation(std::vector<unsigned char *> VData,unsigned char SrcData[])
{
static ULONG64 StrEncryptionVal = 0;
//第一个字节标记加密数组的字节位置
SrcData[0] = (StrEncryptionVal % DataLen + '0' );
for (auto it = VData.begin();it != VData.end();it++)
{
unsigned char * data = *it;
SrcData[1] = (data[SrcData[0] - '0' ]) - SrcData[1];
}
++StrEncryptionVal;
return SrcData;
}
//获取指定的加密数组
unsigned char * DataOperation::GetData_Operation( int nVal)
{
switch (nVal)
{
case 1:
{
return GetData(1);
}
break ;
case 2:
{
return GetData(2);
}
break ;
case 3:
{
return GetData(3);
}
break ;
case 4:
{
return GetData(4);
}
break ;
case 5:
{
return GetData(5);
}
break ;
}
return 0;
}
//解析数据头信息,返回每一次解密需要传入的数据长度(使用加密后的数据前512字节为数据头信息传入函数获取到加密数据以及加密的数据长度等)
int DataOperation::DecryptionHead( char * SrcData)
{
if (0 == SrcData || 512 > strlen (SrcData))
return 0;
char pSrcData[513] = {0};
memcpy (pSrcData,SrcData,512);
if (pSrcData[0] != 'L' || pSrcData[1] != 'K' || pSrcData[2] != 'Y' )
return 0;
//前128位校验数据头信息
int i = 127;
for (;i > 3;i--)
pSrcData[i - 1] = ((pSrcData[i] + i)%128 - pSrcData[i - 1] - 1);
if (pSrcData[i - 1] != 'Y' )
return 0;
//129-134为使用的加密数据
i = 128;
int ii = 0;
memset (m_DecryptionData,0, sizeof (m_DecryptionData));
for (;i < 133;i++)
{
if ( '0' == pSrcData[i])
{
continue ;
}
else
{
m_DecryptionData[ii++] = pSrcData[i];
}
}
//257-261为加密长度
char EncryptionDataLen[5] = {0};
ii = 0;
i = 256;
for (;i < 260;i++)
{
if (pSrcData[i] == '99' )
{
continue ;
}
else
{
EncryptionDataLen[ii++] = pSrcData[i];
}
}
m_EncryptionDataLen = atoi (EncryptionDataLen);
m_DecryptionDataLen = GetDecryptionDataLen(m_EncryptionDataLen);
return m_DecryptionDataLen;
}
//根据指定加密长度获取解密长度
int DataOperation::GetDecryptionDataLen( int nDataLen)
{
if (0 >= nDataLen)
return 0;
int nIndex = 0;
for ( int i = 0;i < nDataLen;(i = i * 2 + 1))
{
nIndex += 2;
}
return nDataLen + nIndex;
}
//解密数据(传入加密后的数据以及数据长度,不要带数据头信息)
char *DataOperation::DecryptionData( const char * SrcData, int & nDataLen)
{
if (0 == SrcData || 0 >= nDataLen)
return 0;
char Data[2048 + 100] = {0};
int nIndex = 0;
int nOffset = 0,nLeft = 0,nCurrent = 0;
int nLen = (m_DecryptionDataLen <= nDataLen ? m_DecryptionDataLen : nDataLen);
//获取解密
int nDecryptionDataLen = strlen (m_DecryptionData);
unsigned char *VData[10] = {0};
int nVDataLen = 0;
for ( int iLen = nDecryptionDataLen;iLen > 0;iLen--)
{
int nVal = m_DecryptionData[iLen - 1];
unsigned char * DataArray = GetData_Operation(nVal);
VData[nVDataLen++] = DataArray;
}
int i = 0;
//开始加密数据
for (;i < nLen;(i = i * 2 + 1))
{
nCurrent = i + nOffset;
if (nCurrent >= nDataLen)
{
break ;
}
//拷贝没有加密的数据
if (0 < nCurrent - nLeft)
{
memcpy (Data + nIndex,SrcData + nLeft,nCurrent - nLeft);
nIndex += (nCurrent - nLeft);
}
unsigned char StrTemp[4] = {SrcData[nCurrent],SrcData[nCurrent + 1],SrcData[nCurrent + 2],0};
if (127 == StrTemp[2])
{
StrTemp[1] = StrTemp[1] + 127;
StrTemp[2] = 0;
}
else if ( '1' == StrTemp[2])
{
StrTemp[1] = 128 - StrTemp[1];
StrTemp[2] = 0;
}
else if ( '0' == StrTemp[2])
{
StrTemp[1] = 0;
StrTemp[2] = 0;
}
else
{
StrTemp[2] = 0;
}
Decryption_Operation(VData,StrTemp,nDecryptionDataLen);
//拷贝转换过的数据
memcpy (Data + nIndex,StrTemp + 1,1);
nIndex += 1;
nOffset += 2;
nLeft = i + nOffset + 1;
}
if (nLeft < nLen && 0 != nIndex)
{
memcpy (Data + nIndex,SrcData + nLeft,nLen - nLeft);
nIndex += nLen - nLeft;
}
else if (0 == nIndex)
{
return Data;
}
nDataLen = nIndex;
return Data;
}
//指定字节进行解密运算
unsigned char *DataOperation::Decryption_Operation(unsigned char * VData[],unsigned char SrcData[], int nVDataLen)
{
for ( int i = 0;i < nVDataLen;i++)
{
unsigned char * data = VData[i];
SrcData[1] = (data[SrcData[0] - '0' ]) - SrcData[1];
}
return SrcData;
}
//加密文件
bool DataOperation::EncryptionFile(CString Filename, bool bCover)
{
//增加随机加密 默认使用2,1数组
SetEncryptionData(5);
SetEncryptionData(4);
if (Filename.IsEmpty())
return false ;
CFile file1,file2;
if (!file1.Open(Filename,CFile::modeRead))
return false ;
ULONG64 nFileLen = file1.GetLength();
if (0 == nFileLen)
return false ;
CString Filename2(Filename.Mid(0,Filename.ReverseFind(_T( '.' ))));
Filename2.AppendFormat(_T( "_Temp%s" ),Filename.Mid(Filename.ReverseFind(_T( '.' )),
Filename.GetLength() - Filename.ReverseFind(_T( '.' ))));
if (!file2.Open(Filename2,CFile::modeCreate | CFile::modeWrite))
return false ;
char StrData[4096] = {0};
int nDataLen = 0;
while (0 < nFileLen)
{
if (2048 <= nFileLen)
{
file1.Read(StrData,2048);
nDataLen = 2048;
char *WriteFile = EncryptionData(StrData,nDataLen);
file2.Write(WriteFile,nDataLen);
nFileLen -= 2048;
}
else
{
file1.Read(StrData,nFileLen);
nDataLen = nFileLen;
char *WriteFile = EncryptionData(StrData,nDataLen);
file2.Write(WriteFile,nDataLen);
nFileLen -= nFileLen;
break ;
}
}
file1.Close();
file2.Close();
if (bCover)
{
USES_CONVERSION;
//覆盖本地文件
int nResult = remove (T2A(Filename));
nResult = rename (T2A(Filename2),T2A(Filename));
}
return true ;
}
//解密文件
bool DataOperation::DecryptionFile(CString Filename, bool bCover)
{
if (Filename.IsEmpty())
return false ;
CFile file1,file2;
if (!file1.Open(Filename,CFile::modeRead))
return false ;
ULONG64 nFileLen = file1.GetLength();
if (512 >= nFileLen)
return false ;
CString Filename2(Filename.Mid(0,Filename.ReverseFind(_T( '.' ))));
Filename2.AppendFormat(_T( "_Temp%s" ),Filename.Mid(Filename.ReverseFind(_T( '.' )),
Filename.GetLength() - Filename.ReverseFind(_T( '.' ))));
if (!file2.Open(Filename2,CFile::modeCreate | CFile::modeWrite))
return false ;
char StrData[2048 + 100] = {0};
int nDataLen = 0;
file1.Read(StrData,512);
//解密数据头
int nDecryptionLen = DecryptionHead(StrData);
if (0 >= nDecryptionLen)
return false ;
nFileLen -= 512;
while (0 < nFileLen)
{
if (nDecryptionLen <= nFileLen)
{
nDataLen = nDecryptionLen;
file1.Read(StrData,nDataLen);
char *WriteFile = DecryptionData(StrData,nDataLen);
memset (StrData,0, strlen (StrData));
memcpy (StrData,WriteFile,nDataLen);
file2.Write(StrData,nDataLen);
nFileLen -= nDecryptionLen;
}
else
{
nDataLen = nFileLen;
file1.Read(StrData,nFileLen);
char *WriteFile = DecryptionData(StrData,nDataLen);
memset (StrData,0, strlen (StrData));
memcpy (StrData,WriteFile,nDataLen);
file2.Write(StrData,nDataLen);
nFileLen -= nFileLen;
break ;
}
}
file1.Close();
file2.Close();
if (bCover)
{
USES_CONVERSION;
//覆盖本地文件
int nResult = remove (T2A(Filename));
nResult = rename (T2A(Filename2),T2A(Filename));
}
return true ;
}
|
下面说下具体函数用法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
//设置加密数据(传入1表示使用unsigned char Data1[] ={255,210,208,179,168,199,202,189,193,0}数组加密)传入类型1-5,
//如果传入数据超过5次,不再记录
//这个函数需要在加密函数使用之前调用,默认采用2、1数组加密
bool SetEncryptionData( int nCount);
//设置每一次加密的数据长度值为0-2048,默认使用2048
bool SetEncryptionLen( int nLen);
//加密数据函数
//返回加密完成的函数
//如果传入的数据超过设置每一次加密的数据长度,将会采用设置的数据长度
//第一次调用会生成512字节数据头与加密后的数据一起返回(比如需要加密3048个字节数据,第一次调用函数返回数据头和2048加密后的数据,第二次调用返回剩下1000个字节加密后的数据)
char *EncryptionData( char * SrcData, int & nDataLen);
//加密文件
//参数一文件完整路径加名称
//参数二 true为覆盖文件 false为创建文件名加_Temp的新文件
bool EncryptionFile(CString Filename, bool bCover);
//解析数据头信息,返回每一次解密需要传入的数据长度(使用加密后的数据前512字节为数据头信息传入函数获取到加密数据以及加密的数据长度等)
int DecryptionHead( char * SrcData);
//解密数据(传入加密后的数据以及数据长度,不要带数据头信息)
//比如解密3048字节长度数据,去掉数据512个字节数据(数据头信息),从513字节开始为需要解析的数据
//nDataLen 为解析数据头返回的每次需要传入的数据长度
char *DecryptionData( const char * SrcData, int & nDataLen);
//解密文件
//参数一文件完整路径加名称
//参数二 true为覆盖文件 false为创建文件名加_Temp的新文件
bool DecryptionFile(CString Filename, bool bCover);
|
函数使用方式参考加密文件和解密文件函数,工程下载地址
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/u010771437/article/details/49705917