马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 sankeyou 于 2012-1-9 21:22 编辑
动态加解密就是说同样的内容,每次加密的结果都不一样,但是还能解出来
例子程序使用 Delphi XE update3 编写, 不保证delphi7可以正常编译(未测试)
支持任何数据动态加解密,如:字符串,结构体等.我目前用于封包加解密中.
加密函数:function Encryption(destinationPtr: Pointer; sourcePtr: Pointer;
sourceLength: integer;
strKey: AnsiString = '@#$%^&21P46YV633F4FFBFB871*()_+-='): integer;
var
keyLength: integer;
newKeyPtr: PByte;
startTime: integer;
keyTime: integer;
rand: integer;
i: integer;
j: integer;
count: integer;
dstPtr: PByte;
srcPtr: PByte;
dstposition: integer;
begin
if (destinationPtr = nil) or (sourcePtr = nil) or (sourceLength = 0) then
begin
Result := 0;
Exit;
end;
newKeyPtr := nil;
// key的长度
keyLength := length(strKey);
try
try
// 内部可修改密匙
newKeyPtr := AllocMem(keyLength + sizeof(Byte));
if newKeyPtr = nil then
begin
Result := 0;
Exit;
end;
// 复制key到新申请的内存中
CopyMemory(newKeyPtr, PAnsiChar(strKey), keyLength);
// 启动时间
startTime := GetTickCount();
// 密匙时间
keyTime := startTime;
// 初始化随机种子并取2-255之间的随机数
Randomize;
rand := Random(253) + 2;
// keyTime 每个字节 = startTime[i] xor rand, 产生一个新的 keyTime
for i := 0 to sizeof(keyTime) - 1 do
PByte(@keyTime)[i] := PByte(@keyTime)[i] xor rand;
// 把 newKeyPtr 和 keyTime 每个字节顺序 xor , 产生一个新的key
count := 0;
for i := 0 to keyLength - 1 do
begin
newKeyPtr[i] := newKeyPtr[i] xor PByte(@keyTime)[count];
inc(count);
if count > 3 then
count := 0;
end;
dstPtr := destinationPtr;
srcPtr := sourcePtr;
for i := 0 to sourceLength - 1 do
begin
dstposition := sizeof(rand) + sizeof(keyTime) + i;
dstPtr[dstposition] := srcPtr[i];
// 当前字节先和 key xor 一遍
for j := 0 to keyLength - 1 do
dstPtr[dstposition] := dstPtr[dstposition] xor newKeyPtr[j];
// 再和startTime xor 一遍
dstPtr[dstposition] := dstPtr[dstposition]
xor PByte(@startTime)[count];
inc(count);
if count > 3 then
count := 0;
end;
// not rand 并与 keyTime 进行 xor
rand := not rand;
rand := rand xor keyTime;
// 将rand 和 keyTime 分别写入前(sizeof(rand) + sizeof(keyTime))个字节中
PInteger(dstPtr)^ := rand;
PInteger(dstPtr + sizeof(rand))^ := keyTime;
// 返回加密后的长度
Result := sourceLength + sizeof(rand) + sizeof(keyTime);
except
Result := 0;
end;
finally
if newKeyPtr <> nil then
FreeMem(newKeyPtr);
end;
end;
解密函数:function Decryption(destinationPtr: Pointer; sourcePtr: Pointer;
sourceLength: integer;
strKey: AnsiString = '@#$%^&21P46YV633F4FFBFB871*()_+-='): integer;
var
keyLength: integer;
newKeyPtr: PByte;
keyTime1: integer;
keyTime2: integer;
rand: integer;
i: integer;
j: integer;
count: integer;
dstPtr: PByte;
srcPtr: PByte;
dstposition: integer;
begin
if (destinationPtr = nil) or (sourcePtr = nil) or (sourceLength < 9) then
begin
Result := 0;
Exit;
end;
newKeyPtr := nil;
// key的长度
keyLength := length(strKey);
// 取出那个随机数
rand := PInteger(sourcePtr)
^ xor (PInteger(integer(sourcePtr) + sizeof(rand)))^;
rand := not rand;
for i := 0 to sizeof(keyTime2) - 1 do
begin
PByte(@keyTime1)[i] := (PByte(sourcePtr) + sizeof(rand))[i];
PByte(@keyTime2)[i] := PByte(@keyTime1)[i] xor rand;
end;
try
try
// 内部可修改密匙
newKeyPtr := AllocMem(keyLength + sizeof(Byte));
if newKeyPtr = nil then
begin
Result := 0;
Exit;
end;
// 复制key到新申请的内存中
CopyMemory(newKeyPtr, PAnsiChar(strKey), keyLength);
// 把 newKeyPtr 和 keyTime 每个字节顺序 xor , 还原原始的key
count := 0;
for i := 0 to keyLength - 1 do
begin
newKeyPtr[i] := newKeyPtr[i] xor PByte(@keyTime1)[count];
inc(count);
if count > 3 then
count := 0;
end;
dstPtr := destinationPtr;
srcPtr := sourcePtr;
sourceLength := sourceLength - (sizeof(rand) + sizeof(keyTime1));
for i := 0 to sourceLength - 1 do
begin
dstposition := sizeof(rand) + sizeof(keyTime1) + i;
dstPtr[i] := srcPtr[dstposition] xor PByte(@keyTime2)[count];
// 当前字节先和 key xor 一遍
for j := 0 to keyLength - 1 do
dstPtr[i] := dstPtr[i] xor newKeyPtr[j];
inc(count);
if count > 3 then
count := 0;
end;
// 返回加密后的长度
Result := sourceLength;
except
Result := 0;
end;
finally
if newKeyPtr <> nil then
FreeMem(newKeyPtr);
end;
end;
有例子下载
PS:加解密的执行效率,取决于Key的长度,key越长就越慢,不可不免,但是这2个函数,效率依然很高,key长一些就相对安全一些.
PS:加密后存储的buffer要比加密前的大8个字节,解密后的buffer比解密前的可以小8个字节.
C++版本连接: http://bbs.fishc.com/forum.php?mod=viewthread&tid=12974&page=1&extra=#pid124384
|