📄 msghash.pas
字号:
{Copyright: Hagen Reddmann mailto:HaReddmann@AOL.COM
Author: Hagen Reddmann
Remarks: freeware, but this Copyright must be included
known Problems: none
Version: 3.0, Part I from Delphi Encryption Compendium (DEC Part I)
Delphi 2-4, BCB 3-4, designed and testet under D3 and D4
Description: Include Objects for calculating various Hash's (fingerprints)
used Hash-Algorithm:
MD4, MD5, SHA, SHA1, RipeMD (128 - 320),
Haval (128 - 256), Snefru, Square, Tiger,
Sapphire II (128 - 320)
used Checksum-Algo:
CRC32, XOR32bit, XOR16bit, CRC16-CCITT, CRC16-Standard
Comments: for Designer's, the Buffer from Method Transform must be readonly
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Digest size, Result from DigestKeySize and Datasize for Digest
MD4 16 byte 128 bit 4x Integer
MD5 16 byte 128 bit 4x Integer
SHA 20 byte 160 bit 5x Integer
SHA1 20 byte 160 bit 5x Integer
RMD128 16 byte 128 bit 4x Integer
RMD160 20 byte 160 bit 5x Integer
RMD256 32 byte 256 bit 8x Integer
RMD320 40 byte 320 bit 10x Integer
Haval256 32 byte 256 bit 8x Integer
Haval224 28 byte 224 bit 7x Integer
Haval192 24 byte 192 bit 6x Integer
Haval160 20 byte 160 bit 5x Integer
Haval128 16 byte 128 bit 4x Integer
Sapphire320 40 byte 320 bit 10x Integer
Sapphire288 36 byte 288 bit 9x Integer
Sapphire256 32 byte 256 bit 8x Integer
Sapphire224 28 byte 224 bit 7x Integer
Sapphire192 24 byte 192 bit 6x Integer
Sapphire160 20 byte 160 bit 5x Integer
Sapphire128 16 byte 128 bit 4x Integer
Snefru 32 byte 256 bit 8x Integer
Square 16 byte 128 bit 4x Integer
Tiger 24 byte 192 bit 6x Integer in D4 used 64bit Arithmetic
XOR16 2 byte 16 bit 1x Word
XOR32 4 byte 32 bit 1x Integer
CRC32 4 byte 32 bit 1x Integer
CRC16 2 byte 16 bit 1x Word
}
unit MsgHash;
interface
{$I MsgVer.inc}
{$I Ver.inc}
uses SysUtils, Classes,
{$IFDEF DEBUG_LOG}
MsgDebug,
{$ENDIF}
MsgDECUtil;
type
{all Hash Classes}
THash_MD4 = class;
THash_RipeMD256 = class;
THash_RipeMD128 = class;
{the Base-Class of all Hashs}
THashClass = class of THash;
THash = class(TProtection)
protected
class function TestVector: Pointer; virtual; {must override}
procedure CodeInit(Action: TPAction); override; {TProtection Methods, You can use a Hash to En/Decode}
procedure CodeDone(Action: TPAction); override; {TProtection Methods}
procedure CodeBuf(var Buffer; const BufferSize: Integer; Action: TPAction); override; {TProtection Methods}
procedure Protect(IsInit: Boolean); {calls any installed Protection}
public
destructor Destroy; override;
procedure Init; virtual;
procedure Calc(const Data; DataSize: Integer); virtual; {must override}
procedure Done; virtual;
function DigestKey: Pointer; virtual; {must override}
function DigestStr(Format: Integer): String;
class function DigestKeySize: Integer; virtual; {must override}
{$IFDEF VER_D4H} // new features from D4
class function CalcBuffer(const Buffer; BufferSize: Integer; Protection: TProtection = nil; Format: Integer = fmtDEFAULT): String; overload;
class function CalcStream(const Stream: TStream; StreamSize: Integer; Protection: TProtection = nil; Format: Integer = fmtDEFAULT): String; overload;
class function CalcString(const Data: String; Protection: TProtection = nil; Format: Integer = fmtDEFAULT): String; overload;
class function CalcFile(const FileName: String; Protection: TProtection = nil; Format: Integer = fmtDEFAULT): String; overload;
{$ELSE}
class function CalcBuffer(const Buffer; BufferSize: Integer; Protection: TProtection; Format: Integer): String;
class function CalcStream(const Stream: TStream; StreamSize: Integer; Protection: TProtection; Format: Integer): String;
class function CalcString(const Data: String; Protection: TProtection; Format: Integer): String;
class function CalcFile(const FileName: String; Protection: TProtection; Format: Integer): String;
{$ENDIF}
{test the correct working}
class function SelfTest: Boolean;
end;
THash_MD4 = class(THash)
private
FCount: LongWord;
FBuffer: array[0..63] of Byte;
FDigest: array[0..9] of LongWord;
protected
class function TestVector: Pointer; override;
procedure Transform(Buffer: PIntArray); virtual;
public
class function DigestKeySize: Integer; override;
procedure Init; override;
procedure Done; override;
procedure Calc(const Data; DataSize: Integer); override;
function DigestKey: Pointer; override;
end;
THash_RipeMD128 = class(THash_MD4) {RACE Integrity Primitives Evaluation Message Digest}
protected
class function TestVector: Pointer; override;
procedure Transform(Buffer: PIntArray); override;
end;
THash_RipeMD256 = class(THash_MD4)
protected
class function TestVector: Pointer; override;
procedure Transform(Buffer: PIntArray); override;
public
{DigestKey-Size 256 bit}
class function DigestKeySize: Integer; override;
procedure Init; override;
end;
function DefaultHashClass: THashClass;
procedure SetDefaultHashClass(HashClass: THashClass);
function RegisterHash(const AHash: THashClass; const AName, ADescription: String): Boolean;
function UnregisterHash(const AHash: THashClass): Boolean;
function HashList: TStrings;
procedure HashNames(List: TStrings);
function GetHashClass(const Name: String): THashClass;
function GetHashName(HashClass: THashClass): String;
implementation
const
// used as default for TCipher in .InitKey(),
// the hashed Password is used as real Key,
// RipeMD256 produce a 256 bit Key (32 Bytes)
// a Key Attack have 2^256 Variants to test, when the
// Cipher all Bit's use, i.E. Blowfish, Gost, SCOP, Twofish
FDefaultHashClass: THashClass = THash_RipeMD256;
FHashList: TStringList = nil;
// RFC2104 HMAC Algorithm Parameters
RFC2104_Size = 64; // Size of Padding in Bytes
RFC2104_IPad = $36; // XOR Value from Inner Pad
RFC2104_OPad = $5C; // XOR Value from outer Pad
function DefaultHashClass: THashClass;
begin
Result := FDefaultHashClass;
end;
procedure SetDefaultHashClass(HashClass: THashClass);
begin
if HashClass = nil then FDefaultHashClass := THash_RipeMD256
else FDefaultHashClass := HashClass;
end;
function RegisterHash(const AHash: THashClass; const AName, ADescription: String): Boolean;
var
I: Integer;
S: String;
begin
Result := False;
if AHash = nil then Exit;
S := Trim(AName);
if S = '' then
begin
S := AHash.ClassName;
if S[1] = 'T' then Delete(S, 1, 1);
I := Pos('_', S);
if I > 0 then Delete(S, 1, I);
end;
S := S + '=' + ADescription;
I := HashList.IndexOfObject(Pointer(AHash));
if I < 0 then HashList.AddObject(S, Pointer(AHash))
else HashList[I] := S;
Result := True;
end;
function UnregisterHash(const AHash: THashClass): Boolean;
var
I: Integer;
begin
Result := False;
repeat
I := HashList.IndexOfObject(Pointer(AHash));
if I < 0 then Break;
Result := True;
HashList.Delete(I);
until False;
end;
function HashList: TStrings;
begin
if not IsObject(FHashList, TStringList) then FHashList := TStringList.Create;
Result := FHashList;
end;
procedure HashNames(List: TStrings);
var
I: Integer;
begin
if not IsObject(List, TStrings) then Exit;
for I := 0 to HashList.Count-1 do
List.AddObject(FHashList.Names[I], FHashList.Objects[I]);
end;
function GetHashClass(const Name: String): THashClass;
var
I: Integer;
N: String;
begin
Result := nil;
N := Name;
I := Pos('_', N);
if I > 0 then Delete(N, 1, I);
for I := 0 to HashList.Count-1 do
if AnsiCompareText(N, GetShortClassName(TClass(FHashList.Objects[I]))) = 0 then
begin
Result := THashClass(FHashList.Objects[I]);
Exit;
end;
I := FHashList.IndexOfName(N);
if I >= 0 then Result := THashClass(FHashList.Objects[I]);
end;
function GetHashName(HashClass: THashClass): String;
var
I: Integer;
begin
I := HashList.IndexOfObject(Pointer(HashClass));
if I >= 0 then Result := FHashList.Names[I]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -