📄 deccipher.pas
字号:
{Copyright: Hagen Reddmann HaReddmann at T-Online dot de
Author: Hagen Reddmann
Remarks: freeware, but this Copyright must be included
known Problems: none
Version: 5.1, Part I from Delphi Encryption Compendium ( DEC Part I)
Delphi 5
* 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.
}
unit DECCipher;
interface
uses SysUtils, Classes, DECUtil, DECFmt;
{$I VER.INC}
type
TCipher_Null = class; // Null cipher, does'nt encrypt, copying only
TCipher_Blowfish = class;
TCipher_Twofish = class; {AES Round 2 Final Candidate}
TCipher_IDEA = class;
TCipher_Cast256 = class;
TCipher_Mars = class; {AES Round 2 Final Candidate}
TCipher_RC4 = class; {Streamcipher in as Block Cipher}
TCipher_RC6 = class; {AES Round 2 Final Candidate}
TCipher_Rijndael = class; {AES Round 2 Final Candidate}
TCipher_Square = class;
TCipher_SCOP = class; {Streamcipher on Longword, very fast}
TCipher_Sapphire = class; {Stream Cipher, eq. Design from german ENIGMA Machine}
TCipher_1DES = class; {Single DES 8 byte Blocksize, 8 byte Keysize 56 bits relevant}
TCipher_2DES = class; {Triple DES 8 byte Blocksize, 16 byte Keysize 112 bits relevant}
TCipher_3DES = class; {Triple DES 8 byte Blocksize, 24 byte Keysize 168 bits relevant}
TCipher_2DDES = class; {Triple DES 16 byte Blocksize, 16 byte Keysize 112 bits relevant}
TCipher_3DDES = class; {Triple DES 16 byte Blocksize, 24 byte Keysize 168 bits relevant}
TCipher_3TDES = class; {Triple DES 24 byte Blocksize, 24 byte Keysize 168 bits relevant}
TCipher_3Way = class;
TCipher_Cast128 = class;
TCipher_Gost = class;
TCipher_Misty = class;
TCipher_NewDES = class;
TCipher_Q128 = class;
TCipher_RC2 = class;
TCipher_RC5 = class;
TCipher_SAFER = class;
TCipher_Shark = class;
TCipher_Skipjack = class;
TCipher_TEA = class;
TCipher_TEAN = class;
TCipherContext = packed record
KeySize: Integer; // maximal key size in bytes
BlockSize: Integer; // mininmal block size in bytes, eg. 1 = Streamcipher
BufferSize: Integer; // internal buffersize in bytes
UserSize: Integer; // internal size in bytes of cipher dependend structures
UserSave: Boolean;
end;
TCipherState = (csNew, csInitialized, csEncode, csDecode, csPadded, csDone);
TCipherStates = set of TCipherState;
{ TCipher.State represents the internal state of processing
csNew = cipher isn't initialized, .Init() must be called before en/decode
csInitialized = cipher is initialized by .Init(), eg. Keysetup was processed
csEncode = Encodeing was started, and more chunks can be encoded, but not decoded
csDecode = Decodeing was started, and more chunks can be decoded, but not encoded
csPadded = trough En/Decodeing the messagechunks are padded, no more chunks can
be processed, the cipher is blocked.
csDone = Processing is finished and Cipher.Done was called. Now new En/Decoding
can be started without calling .Init() before. csDone is basicaly
identical to csInitialized, except Cipher.Buffer holds the encrypted
last state of Cipher.Feedback, thus Cipher.Buffer can be used as C-MAC.}
TCipherMode = (cmCTSx, cmCBCx, cmCFB8, cmCFBx, cmOFB8, cmOFBx, cmCFS8, cmCFSx, cmECBx);
{ cmCTSx = double CBC, with CFS8 padding of truncated final block
cmCBCx = Cipher Block Chainung, with CFB8 padding of truncated final block
cmCFB8 = 8bit Cipher Feedback mode
cmCFBx = CFB on Blocksize of Cipher
cmOFB8 = 8bit Output Feedback mode
cmOFBx = OFB on Blocksize bytes
cmCFS8 = 8Bit CFS, double CFB
cmCFSx = CFS on Blocksize bytes
cmECBx = Electronic Code Book
Modes cmCBCx, cmCTSx, cmCFBx, cmOFBx, cmCFSx, cmECBx working on Blocks of
Cipher.BufferSize bytes, on Blockcipher that's equal to Cipher.BlockSize.
Modes cmCFB8, cmOFB8, cmCFS8 work on 8 bit Feedback Shift Registers.
Modes cmCTSx, cmCFSx, cmCFS8 are prohibitary modes developed by me. These modes
works such as cmCBCx, cmCFBx, cmCFB8 but with double XOR'ing of the inputstream
into Feedback register.
Mode cmECBx need message padding to a multiple of Cipher.BlockSize and should
be only used in 1byte Streamciphers.
Modes cmCTSx, cmCBCx need no external padding, because internal the last truncated
block is padded by cmCFS8 or cmCFB8. After padding these Mode can't be used to
process more data. If it needed to process chunks of data then each chunk must
be algined to Cipher.BufferSize bytes.
Modes cmCFBx,cmCFB8,cmOFBx,cmOFB8,cmCFSx,cmCFS8 need no padding.
}
TDECCipherCodeEvent = procedure(const Source; var Dest; DataSize: Integer) of object;
TDECCipherClass = class of TDECCipher;
TDECCipher = class(TDECObject)
private
FState: TCipherState;
FMode: TCipherMode;
FData: PByteArray;
FDataSize: Integer;
procedure SetMode(Value: TCipherMode);
protected
FBufferSize: Integer;
FBufferIndex: Integer;
FUserSize: Integer;
FBuffer: PByteArray;
FVector: PByteArray;
FFeedback: PByteArray;
FUser: Pointer;
FUserSave: Pointer;
procedure CheckState(States: TCipherStates);
procedure DoInit(const Key; Size: Integer); virtual; abstract;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); virtual; abstract;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); virtual; abstract;
public
constructor Create; override;
destructor Destroy; override;
class function Context: TCipherContext; virtual; abstract;
procedure Init(const Key; Size: Integer; const IVector; IVectorSize: Integer; IFiller: Byte = $FF); overload;
procedure Init(const Key: Binary; const IVector: Binary = ''; IFiller: Byte = $FF); overload;
procedure Done;
procedure Protect; virtual;
procedure Encode(const Source; var Dest; DataSize: Integer);
procedure Decode(const Source; var Dest; DataSize: Integer);
function EncodeBinary(const Source: Binary; Format: TDECFormatClass = nil): Binary;
function DecodeBinary(const Source: Binary; Format: TDECFormatClass = nil): Binary;
procedure EncodeFile(const Source, Dest: String; const Progress: IDECProgress = nil);
procedure DecodeFile(const Source, Dest: String; const Progress: IDECProgress = nil);
procedure EncodeStream(const Source, Dest: TStream; const DataSize: Int64; const Progress: IDECProgress = nil);
procedure DecodeStream(const Source, Dest: TStream; const DataSize: Int64; const Progress: IDECProgress = nil);
function CalcMAC(Format: TDECFormatClass = nil): Binary;
property InitVectorSize: Integer read FBufferSize;
property InitVector: PByteArray read FVector; // buffer size bytes
property Feedback: PByteArray read FFeedback; // buffer size bytes
property State: TCipherState read FState;
published
property Mode: TCipherMode read FMode write SetMode;
end;
TCipher_Null = class(TDECCipher)
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_Blowfish = class(TDECCipher)
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_Twofish = class(TDECCipher)
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_IDEA = class(TDECCipher) {International Data Encryption Algorithm }
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_Cast256 = class(TDECCipher)
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_Mars = class(TDECCipher)
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_RC4 = class(TDECCipher)
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_RC6 = class(TDECCipher)
private
FRounds: Integer; {16-24, default 20}
procedure SetRounds(Value: Integer);
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
published
property Rounds: Integer read FRounds write SetRounds;
end;
TCipher_Rijndael = class(TDECCipher)
private
FRounds: Integer;
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
published
property Rounds: Integer read FRounds;
end;
TCipher_Square = class(TDECCipher)
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_SCOP = class(TDECCipher) {Stream Cipher in Blockmode}
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_Sapphire = class(TDECCipher)
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_1DES = class(TDECCipher)
protected
procedure DoInitKey(const Data: array of Byte; Key: PLongArray; Reverse: Boolean);
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_2DES = class(TCipher_1DES)
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_3DES = class(TCipher_1DES)
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_2DDES = class(TCipher_2DES)
protected
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_3DDES = class(TCipher_3DES)
protected
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_3TDES = class(TCipher_3DES)
protected
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_3Way = class(TDECCipher)
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_Cast128 = class(TDECCipher) {Carlisle Adams and Stafford Tavares }
private
FRounds: Integer;
procedure SetRounds(Value: Integer);
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
published
property Rounds: Integer read FRounds write SetRounds;
end;
TCipher_Gost = class(TDECCipher) {russian Cipher}
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_Misty = class(TDECCipher)
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
{ This algorithm resembles the Data Encryption Standard (DES), but is easier
to implement in software and is supposed to be more secure.
It is not to be confused with another algorithm--known by the
same name--which is simply DES without the initial and final
permutations. The NewDES here is a completely different algorithm.}
TCipher_NewDES = class(TDECCipher)
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_Q128 = class(TDECCipher)
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_RC2 = class(TDECCipher)
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
class function Context: TCipherContext; override;
end;
TCipher_RC5 = class(TDECCipher)
private
FRounds: Integer; {8-16, default 12}
procedure SetRounds(Value: Integer);
protected
procedure DoInit(const Key; Size: Integer); override;
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -