git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.DevExpressVCL@55 05c56307-c608-d34a-929d-697000501d7a
331 lines
11 KiB
ObjectPascal
331 lines
11 KiB
ObjectPascal
{*******************************************************************}
|
|
{ }
|
|
{ Developer Express Visual Component Library }
|
|
{ ExpressPrinting System COMPONENT SUITE }
|
|
{ }
|
|
{ Copyright (C) 1998-2009 Developer Express Inc. }
|
|
{ ALL RIGHTS RESERVED }
|
|
{ }
|
|
{ The entire contents of this file is protected by U.S. and }
|
|
{ International Copyright Laws. Unauthorized reproduction, }
|
|
{ reverse-engineering, and distribution of all or any portion of }
|
|
{ the code contained in this file is strictly prohibited and may }
|
|
{ result in severe civil and criminal penalties and will be }
|
|
{ prosecuted to the maximum extent possible under the law. }
|
|
{ }
|
|
{ RESTRICTIONS }
|
|
{ }
|
|
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
|
|
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
|
|
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
|
|
{ LICENSED TO DISTRIBUTE THE EXPRESSPRINTINGSYSTEM AND }
|
|
{ ALL ACCOMPANYING VCL CONTROLS AS PART OF AN }
|
|
{ EXECUTABLE PROGRAM ONLY. }
|
|
{ }
|
|
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
|
|
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
|
|
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
|
|
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
|
|
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
|
|
{ }
|
|
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
|
|
{ ADDITIONAL RESTRICTIONS. }
|
|
{ }
|
|
{*******************************************************************}
|
|
|
|
unit dxPSPDFCrypt;
|
|
|
|
interface
|
|
|
|
uses
|
|
Windows, SysUtils, Classes, Math, dxCore;
|
|
|
|
type
|
|
TdxRC4Key = array[0..255] of Byte;
|
|
|
|
TdxMD5Byte16 = array[0..15] of Byte;
|
|
TdxMD5Byte64 = array[0..63] of Byte;
|
|
PdxMD5Byte64 = ^TdxMD5Byte64;
|
|
|
|
TdxMD5Int2 = array[0..1] of Cardinal;
|
|
TdxMD5Int4 = array[0..3] of Cardinal;
|
|
TdxMD5Int16 = array[0..15] of Cardinal;
|
|
PdxMD5Int16 = ^TdxMD5Int16;
|
|
|
|
TdxMD5Context = record
|
|
State: TdxMD5Int4;
|
|
Count: TdxMD5Int2;
|
|
Buffer: TdxMD5Byte64;
|
|
BufferLen: Cardinal;
|
|
end;
|
|
|
|
function dxMD5CalcStr(const S: string): string;
|
|
function dxMD5DigestToString(const ADigest: TdxMD5Byte16): string;
|
|
procedure dxMD5Calc(AInput: PByteArray; AInputLength: Integer; var ADigest: TdxMD5Byte16);
|
|
procedure dxMD5Final(var AContext: TdxMD5Context; var ADigest: TdxMD5Byte16);
|
|
procedure dxMD5Init(var AContext: TdxMD5Context);
|
|
procedure dxMD5Update(var AContext: TdxMD5Context; AInput: PByteArray; AInputLength: Integer); overload;
|
|
procedure dxMD5Update(var AContext: TdxMD5Context; const S: AnsiString); overload;
|
|
|
|
procedure dxRC4Crypt(var AKey: TdxRC4Key; AInData, AOutData: PByteArray; ADataSize: Integer);
|
|
procedure dxRC4Initialize(out AKey: TdxRC4Key; APassword: PByteArray; APasswordLength: Integer);
|
|
implementation
|
|
|
|
const
|
|
FFTable: array[0..15] of LongWord = (
|
|
$d76aa478, $e8c7b756, $242070db, $c1bdceee,
|
|
$f57c0faf, $4787c62a, $a8304613, $fd469501,
|
|
$698098d8, $8b44f7af, $ffff5bb1, $895cd7be,
|
|
$6b901122, $fd987193, $a679438e, $49b40821
|
|
);
|
|
|
|
GGTable: array[0..15] of LongWord = (
|
|
$f61e2562, $c040b340, $265e5a51, $e9b6c7aa,
|
|
$d62f105d, $02441453, $d8a1e681, $e7d3fbc8,
|
|
$21e1cde6, $c33707d6, $f4d50d87, $455a14ed,
|
|
$a9e3e905, $fcefa3f8, $676f02d9, $8d2a4c8a
|
|
);
|
|
|
|
HHTable: array[0..15] of LongWord = (
|
|
$fffa3942, $8771f681, $6d9d6122, $fde5380c,
|
|
$a4beea44, $4bdecfa9, $f6bb4b60, $bebfbc70,
|
|
$289b7ec6, $eaa127fa, $d4ef3085, $04881d05,
|
|
$d9d4d039, $e6db99e5, $1fa27cf8, $c4ac5665
|
|
);
|
|
|
|
IITable: array[0..15] of LongWord = (
|
|
$f4292244, $432aff97, $ab9423a7, $fc93a039,
|
|
$655b59c3, $8f0ccc92, $ffeff47d, $85845dd1,
|
|
$6fa87e4f, $fe2ce6e0, $a3014314, $4e0811a1,
|
|
$f7537e82, $bd3af235, $2ad7d2bb, $eb86d391
|
|
);
|
|
|
|
function ROL(X, N: LongWord): LongWord;
|
|
begin
|
|
Result := (X shl N) or (X shr (32 - N));
|
|
end;
|
|
|
|
function FF(A, B, C, D, X, S, AC: LongWord): LongWord;
|
|
begin
|
|
Result := ROL(A + X + AC + (B and C or not B and D), S) + B;
|
|
end;
|
|
|
|
function GG(A, B, C, D, X, S, AC: LongWord): LongWord;
|
|
begin
|
|
Result := ROL(A + X + AC + (B and D or C and not D), S) + B;
|
|
end;
|
|
|
|
function HH(A, B, C, D, X, S, AC: LongWord): LongWord;
|
|
begin
|
|
Result := ROL(A + X + AC + (B xor C xor D), S) + B;
|
|
end;
|
|
|
|
function II(A, B, C, D, X, S, AC: LongWord): LongWord;
|
|
begin
|
|
Result := ROL(A + X + AC + (C xor (B or not D)), S) + B;
|
|
end;
|
|
|
|
procedure dxMD5Init(var AContext: TdxMD5Context);
|
|
begin
|
|
ZeroMemory(@AContext, SizeOf(AContext));
|
|
AContext.State[0] := $67452301;
|
|
AContext.State[1] := $EFCDAB89;
|
|
AContext.State[2] := $98BADCFE;
|
|
AContext.State[3] := $10325476;
|
|
end;
|
|
|
|
procedure dxMD5Transform(var AAccumulator: TdxMD5Int4; const ABuf: PdxMD5Int16);
|
|
|
|
function CalcPos(ARow, AOffset: Integer): Integer;
|
|
begin
|
|
Result := ARow * 4 + AOffset;
|
|
if Result < 0 then
|
|
Inc(Result, 16);
|
|
if Result >= 16 then
|
|
Dec(Result, 16);
|
|
end;
|
|
|
|
var
|
|
A, B, C, D: LongWord;
|
|
I: Integer;
|
|
begin
|
|
A := AAccumulator[0];
|
|
B := AAccumulator[1];
|
|
C := AAccumulator[2];
|
|
D := AAccumulator[3];
|
|
|
|
for I := 0 to 3 do
|
|
begin
|
|
A := FF(A, B, C, D, ABuf^[CalcPos(I, 0)], 7, FFTable[4 * I + 0]);
|
|
D := FF(D, A, B, C, ABuf^[CalcPos(I, 1)], 12, FFTable[4 * I + 1]);
|
|
C := FF(C, D, A, B, ABuf^[CalcPos(I, 2)], 17, FFTable[4 * I + 2]);
|
|
B := FF(B, C, D, A, ABuf^[CalcPos(I, 3)], 22, FFTable[4 * I + 3]);
|
|
end;
|
|
|
|
for I := 0 to 3 do
|
|
begin
|
|
A := GG(A, B, C, D, ABuf^[CalcPos(I, 1)], 5, GGTable[4 * I + 0]);
|
|
D := GG(D, A, B, C, ABuf^[CalcPos(I, 6)], 9, GGTable[4 * I + 1]);
|
|
C := GG(C, D, A, B, ABuf^[CalcPos(I, 11)], 14, GGTable[4 * I + 2]);
|
|
B := GG(B, C, D, A, ABuf^[CalcPos(I, 0)], 20, GGTable[4 * I + 3]);
|
|
end;
|
|
|
|
for I := 0 to 3 do
|
|
begin
|
|
A := HH(A, B, C, D, ABuf^[CalcPos(-I, 5)], 4, HHTable[4 * I + 0]);
|
|
D := HH(D, A, B, C, ABuf^[CalcPos(-I, 8)], 11, HHTable[4 * I + 1]);
|
|
C := HH(C, D, A, B, ABuf^[CalcPos(-I, 11)], 16, HHTable[4 * I + 2]);
|
|
B := HH(B, C, D, A, ABuf^[CalcPos(-I, 14)], 23, HHTable[4 * I + 3]);
|
|
end;
|
|
|
|
for I := 0 to 3 do
|
|
begin
|
|
A := II(A, B, C, D, ABuf^[CalcPos(-I, 0)], 6, IITable[4 * I + 0]);
|
|
D := II(D, A, B, C, ABuf^[CalcPos(-I, 7)], 10, IITable[4 * I + 1]);
|
|
C := II(C, D, A, B, ABuf^[CalcPos(-I, 14)], 15, IITable[4 * I + 2]);
|
|
B := II(B, C, D, A, ABuf^[CalcPos(-I, 5)], 21, IITable[4 * I + 3]);
|
|
end;
|
|
|
|
Inc(AAccumulator[0], A);
|
|
Inc(AAccumulator[1], B);
|
|
Inc(AAccumulator[2], C);
|
|
Inc(AAccumulator[3], D);
|
|
end;
|
|
|
|
procedure dxMD5Update(var AContext: TdxMD5Context; const S: AnsiString);
|
|
begin
|
|
dxMD5Update(AContext, @S[1], Length(S));
|
|
end;
|
|
|
|
procedure dxMD5Update(var AContext: TdxMD5Context; AInput: PByteArray; AInputLength: Integer);
|
|
const
|
|
SplitPartSize = 64;
|
|
var
|
|
AIndex: Integer;
|
|
ALeft: Integer;
|
|
begin
|
|
AIndex := 0;
|
|
if Integer(AInputLength shl 3) < 0 then
|
|
Inc(AContext.Count[1]);
|
|
|
|
Inc(AContext.Count[0], AInputLength shl 3);
|
|
Inc(AContext.Count[1], AInputLength shr 29);
|
|
|
|
if AContext.BufferLen > 0 then
|
|
begin
|
|
ALeft := Min(AInputLength, SplitPartSize - AContext.BufferLen);
|
|
Move(AInput^[AIndex], AContext.Buffer[AContext.BufferLen], ALeft);
|
|
Inc(AContext.BufferLen, ALeft);
|
|
Inc(AIndex, ALeft);
|
|
if AContext.BufferLen < SplitPartSize then
|
|
Exit;
|
|
dxMD5Transform(AContext.State, @AContext.Buffer[0]);
|
|
AContext.BufferLen := 0;
|
|
end;
|
|
|
|
while AIndex + SplitPartSize <= AInputLength do
|
|
begin
|
|
dxMD5Transform(AContext.State, @AInput^[AIndex]);
|
|
Inc(AIndex, SplitPartSize);
|
|
end;
|
|
|
|
if AInputLength > AIndex then
|
|
begin
|
|
AContext.BufferLen := AInputLength - AIndex;
|
|
Move(AInput^[AIndex], AContext.Buffer[0], AContext.BufferLen);
|
|
end;
|
|
end;
|
|
|
|
procedure dxMD5Final(var AContext: TdxMD5Context; var ADigest: TdxMD5Byte16);
|
|
var
|
|
AWorkBuf: TdxMD5Byte64;
|
|
AWorkLen: Cardinal;
|
|
begin
|
|
ADigest := TdxMD5Byte16(AContext.State);
|
|
Move(AContext.Buffer, AWorkBuf, AContext.BufferLen);
|
|
AWorkBuf[AContext.BufferLen] := $80;
|
|
AWorkLen := AContext.BufferLen + 1;
|
|
if AWorkLen > 56 then
|
|
begin
|
|
FillChar(AWorkBuf[AWorkLen], 64 - AWorkLen, 0);
|
|
dxMD5Transform(TdxMD5Int4(ADigest), @AWorkBuf[0]);
|
|
AWorkLen := 0
|
|
end;
|
|
FillChar(AWorkBuf[AWorkLen], 56 - AWorkLen, 0);
|
|
TdxMD5Int16(AWorkBuf)[14] := AContext.Count[0];
|
|
TdxMD5Int16(AWorkBuf)[15] := AContext.Count[1];
|
|
dxMD5Transform(TdxMD5Int4(ADigest), @AWorkBuf[0]);
|
|
FillChar(AContext, SizeOf(AContext), 0);
|
|
end;
|
|
|
|
procedure dxMD5Calc(AInput: PByteArray; AInputLength: Integer; var ADigest: TdxMD5Byte16);
|
|
var
|
|
AContext: TdxMD5Context;
|
|
begin
|
|
dxMD5Init(AContext);
|
|
dxMD5Update(AContext, AInput, AInputLength);
|
|
dxMD5Final(AContext, ADigest);
|
|
end;
|
|
|
|
function dxMD5CalcStr(const S: string): string;
|
|
var
|
|
AAnsiString: AnsiString;
|
|
ADigest: TdxMD5Byte16;
|
|
begin
|
|
AAnsiString := dxStringToAnsiString(S);
|
|
dxMD5Calc(@AAnsiString[1], Length(AAnsiString), ADigest);
|
|
Result := dxMD5DigestToString(ADigest);
|
|
end;
|
|
|
|
function dxMD5DigestToString(const ADigest: TdxMD5Byte16): string;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := '';
|
|
for I := 0 to High(ADigest) do
|
|
Result := Result + IntToHex(ADigest[I], 2);
|
|
end;
|
|
|
|
procedure dxRC4Initialize(out AKey: TdxRC4Key; APassword: PByteArray; APasswordLength: Integer);
|
|
var
|
|
ATempKey: TdxRC4Key;
|
|
I, J, K: Integer;
|
|
begin
|
|
for I := 0 to 255 do
|
|
begin
|
|
ATempKey[I] := APassword^[I mod APasswordLength];
|
|
AKey[I] := I;
|
|
end;
|
|
|
|
J := 0;
|
|
for I := 0 to 255 do
|
|
begin
|
|
J := (J + AKey[I] + ATempKey[I]) and $FF;
|
|
K := AKey[I];
|
|
AKey[I] := AKey[J];
|
|
AKey[j] := K;
|
|
end;
|
|
end;
|
|
|
|
procedure dxRC4Crypt(var AKey: TdxRC4Key; AInData, AOutData: PByteArray; ADataSize: Integer);
|
|
var
|
|
T, K, I, J: Integer;
|
|
begin
|
|
I := 0;
|
|
J := 0;
|
|
for K := 0 to ADataSize - 1 do
|
|
begin
|
|
I := Byte(I + 1);
|
|
J := Byte(J + AKey[I]);
|
|
|
|
T := AKey[I];
|
|
AKey[I] := AKey[J];
|
|
AKey[J] := T;
|
|
|
|
T := Byte(AKey[I] + AKey[J]);
|
|
AOutData^[K] := AInData^[K] xor AKey[T];
|
|
end;
|
|
end;
|
|
|
|
end.
|