这里是DES加密源码:<br>{*******************************************************************************<br>* Unit : TDES *<br>********************************************************************************<br>* Purpose : Encapulates the DES cipher cipher with various cipher modes *<br>********************************************************************************<br>* Copyright : This component is copyright TSM Inc. 1999 *<br>* This source code may not be distributed to third parties in *<br>* or in part without the written permission of TSM Inc. *<br>* All rights reserved. Liability limited to replacement of *<br>* this original source code in the case of loss or damage because *<br>* the use or misuse of this software. *<br>********************************************************************************<br>* Version : 25.02.98 - 1.0 Original component *<br>* 08.03.98 - 1.01 Additional cipher modes added *<br>* 08.04.98 - 1.02 Fix OFB mode *<br>* 20.07.98 - 1.03 Added base64 encoding to en/decrypt string *<br>* 13.08.98 - 1.03a Changed GetVersion to deliver reg info *<br>* 15.08.98 - 1.10 Delphi4 / CBC MAC support added *<br>* 05.10.98 - 1.11 Added Stream functionality *<br>* 22.01.99 - 1.14 Error in En- & Decrypt file/ stream resolved *<br>* 26.03.99 - 1.14a Init error in "InitialiseString" fixed *<br>********************************************************************************<br>* Switches : REGISTERED - Compiles in the registered mode (without nag msg.) *<br>* COMPONENT - Compiles as a VCL component (otherwise unit) *<br>* COMMANDLINE- Allows override of mode from command line compiler *<br>*******************************************************************************}<br><br>{********************************************************************************<br> 修改 : 由于控件在对能被4K整除文件解密时,会产生内存访问错误,至使导致<br> 解密失败,而出现乱码现象,现经过修改,修改用 '// 2001.6.12'<br> 作标示,并把以前的代码进行了注释。<br> 修改日期: 2001.6.12<br>*******************************************************************************}<br>{********************************************************************************<br> 修改 : 支持源数据CRC校验,并可置初值<br> 修改日期: 2001.11.2<br>*******************************************************************************}<br>{********************************************************************************<br> 修改 : 支持输入输出流的后部份数据的加密解密<br> 修改日期: 2001.11.3<br>*******************************************************************************}<br><br>{$R-} {$A-} {$Q-}<br>{$ifdef VER125}<br> // fix for CB4<br> {$define VER120}<br>{$endif}<br>{$ifdef VER130}<br> // fix for Delphi5<br> {$define VER120}<br>{$endif}<br><br>{$ifndef COMMANDLINE} // Commanline overrides the follwing presets<br> {$define NOTREGISTERED} //(NOTREGISTERED, FREEWARE, REGISTERED)<br> {$define COMPONENT} //(COMPONENT, OBJECT)<br>{$endif}<br><br> {**************************************************************************<br> ************ This section of code implements the 64 bit limit *************<br> ************ imposed by the Wassennar agreement. The key is *************<br> ************ limited to 64 bits. Should you be in a country *************<br> ************ where the Wassennar agreement is not in force, *************<br> ************ undefine the WASSENAAR_LIMITED variable. *************<br> **************************************************************************}<br>{$define UNLIMITED} // WASSENAAR_LIMITED, UNLIMITED<br><br>unit des;<br><br>interface<br><br>uses<br> Classes, SysUtils, crc;<br><br>const<br> {general constants}<br> BLOCKSIZE = 8; // DES has an 8 byte block<br> BUFFERSIZE = 4096; // the buffer for file encryption<br><br><br><br>{*******************************************************************************<br>* Type : LongWord (only for D2/D3/CB3) *<br>********************************************************************************<br>* Purpose : Defines the Longword type. This is native for D4,D5,CB4 *<br>*******************************************************************************}<br>{$ifndef VER120}<br>type LongWord = Integer;<br>{$endif}<br><br>{*******************************************************************************<br>* Type : PInteger *<br>********************************************************************************<br>* Purpose : Defines the pointer to the LongWordType *<br>*******************************************************************************}<br>type PInteger = ^LongWord;<br><br>{*******************************************************************************<br>* Type : TIntArray *<br>********************************************************************************<br>* Purpose : Defines an array large enough for all purposes *<br>*******************************************************************************}<br>type TIntArray = array[0..1023] of LongWord;<br><br>{*******************************************************************************<br>* Type : PIntArray *<br>********************************************************************************<br>* Purpose : Defines the pointer to the IntArray type *<br>*******************************************************************************}<br>type PIntArray = ^TIntArray;<br><br>{*******************************************************************************<br>* Type : EKeyError *<br>********************************************************************************<br>* Purpose : Exception raised when key setup incomplete for a given mode *<br>*******************************************************************************}<br>type EKeyError = class(Exception);<br><br>{*******************************************************************************<br>* Type : EFileError *<br>********************************************************************************<br>* Purpose : Exception raised when file manipulation creates an error *<br>*******************************************************************************}<br>type EFileError = class(Exception);<br><br>{*******************************************************************************<br>* Type : EInputError *<br>********************************************************************************<br>* Purpose : Exception raised when the input string for decryptstring suspect *<br>*******************************************************************************}<br>type EInputError = class(Exception);<br><br>{*******************************************************************************<br>* Type : TBlock *<br>********************************************************************************<br>* Purpose : Defines the basic element of enc/decryption *<br>*******************************************************************************}<br>type TBlock = array[0..(BLOCKSIZE - 1)] of Byte;<br><br>{*******************************************************************************<br>* Type : PBlock *<br>********************************************************************************<br>* Purpose : Pointer to the type TBlock *<br>*******************************************************************************}<br>type PBlock = ^TBlock;<br><br>{*******************************************************************************<br>* Type : TDES_ctx *<br>********************************************************************************<br>* Purpose : Defines context variable for TDES *<br>*******************************************************************************}<br>type Tdes_ctx = record<br> KeyInit: Boolean; // Shows if the password has been initialised<br> IVInit: Boolean; // Shows if the IV has been initialised<br> IV: TBlock;<br> ct: TBlock;<br><br> FEncKey: array [0..31] of LongWord;<br> FDecKey: array [0..31] of LongWord;<br><br> case Integer of<br> 0: (ByteBuffer: TBlock);<br> 1: (LongBuffer: array[0..1] of LongInt);<br>end; {Tdes_ctx}<br><br>{*******************************************************************************<br>* Type : TCiphermode *<br>********************************************************************************<br>* Purpose : Defines possible modes for TDES *<br>*******************************************************************************}<br>type TCipherMode = (CBC, ECB, CFB, OFB);<br><br>{*******************************************************************************<br>* Type : TStringMode *<br>********************************************************************************<br>* Purpose : Defines possible string modes for the En/Decrypt string *<br>*******************************************************************************}<br>type TStringMode = (smEncode, smNormal);<br><br>{*******************************************************************************<br>* Type : TDES *<br>********************************************************************************<br>* Purpose : Defines TDES *<br>*******************************************************************************}<br>{$ifdef COMPONENT}<br>type TDES = class(TComponent)<br>{$else}<br>type TDES = class(TObject)<br>{$endif}<br> private<br> ctx: Tdes_ctx;<br><br> // buffer for larger encryptions<br> FBuffer: array[0..BUFFERSIZE+BLOCKSIZE] of BYTE; {Local Copy of Data}<br> PtrBuffer: PBlock;<br> FCipherMode: TCipherMode;<br> FStringMode: TStringMode;<br> FCrcCaclFlage:Boolean;<br> FCrc32Value: Integer;<br> FEncDecNoPosFlage:Boolean;<br><br> // these routines link to the core block routines of the algorithm<br> procedure DES_Core_Key_Setup(const KeyToSet: TBlock);<br> procedure DES_Core_Block_Encrypt;<br> procedure DES_Core_Block_Decrypt;<br> procedure DES_core_make_key(const Data: array of Byte; Key: PInteger; Reverse: Boolean);<br><br> // Internal encryption primitives<br> procedure EncryptBuffer(const Len: integer);<br> procedure DecryptBuffer(const Len: integer);<br> procedure EncryptBlockMode;<br> procedure DecryptBlockMode;<br><br> // Base64 functions<br> function EncodeString(InputString: string): string;<br> function DecodeString(InputString: string): string;<br><br> // Implemnetation primitives<br> procedure CheckKeys;<br> public<br> // these calls are used to load the key and the IV<br> procedure InitialiseString(const Key: string);<br> procedure InitialiseByte(const Key: array of byte; Keylength: integer);<br> procedure LoadIVString(const IVString: string);<br> procedure LoadIVByte(const IVByte: array of Byte; IVLength: integer);<br><br> // These calls perform the operation using the mode specified in CipherMode<br> procedure EncBlock(const Input: TBlock; var Output: TBlock);<br> procedure DecBlock(const Input: TBlock; var Output: TBlock);<br> procedure EncFile(const InputFileName: string; OutputFileName: string);<br> procedure DecFile(const InputFileName: string; OutputFileName: string);<br> procedure EncStream(const Input: TStream; const Output: TStream);<br> procedure DecStream(const Input: TStream; const Output: TStream);<br> procedure EncString(const Input: string; var Output: string);<br> procedure DecString(const Input: string; var Output: string);<br><br> // this returns the CBC-MAC of the data put through DES<br> procedure CBCMACBlock(var MAC:TBlock);<br> procedure CBCMACString(var MAC: string);<br><br> // Burn clears any sensitive information<br> procedure Burn;<br><br> // returns the version of the component<br> function GetVersion: string;<br><br> {$ifdef COMPONENT}<br> published<br> property CipherMode: TCipherMode read FCipherMode write FCipherMode;<br> property StringMode: TStringMode read FStringMode write FStringMode;<br> {$else}<br> procedure SetCipherMode(const Value: TCipherMode);<br> function GetCipherMode: TCipherMode;<br> procedure SetStringMode(const Value: TStringMode);<br> function GetStringMode: TStringMode;<br> {$endif}<br> property CrcCaclFlage:Boolean read FCrcCaclFlage write FCrcCaclFlage default False;<br> property Crc32Value:Integer read FCrc32Value write FCrc32Value default 0;<br> property EncDecNoPosFlage:Boolean read FEncDecNoPosFlage write FEncDecNoPosFlage default False;<br><br>end;<br><br>{$ifdef COMPONENT}<br>procedure Register;<br>{$endif}<br><br>implementation<br><br>uses Windows, Dialogs;<br><br>const<br> // new implementation<br>{this is set to SwapInt for <= 386 and BSwapInt >= 486 CPU, don't modify}<br> SwapInteger : function(Value: LongWord): LongWord = nil;<br><br><br> RELVER = '1.15'; // Version number<br> LIT_COMPNAME = 'DES';<br> LIT_KEY_NOT_SET = LIT_COMPNAME + ': Key not set';<br> LIT_IV_NOT_SET = LIT_COMPNAME + ': IV not set';<br> LIT_KEY_LENGTH = LIT_COMPNAME + ': Key must be between 1 and 8 bytes';<br> LIT_INFILE_NOT_FOUND = LIT_COMPNAME + ': Input file not found';<br> LIT_CBC_NOT_SET = LIT_COMPNAME + ': Mode must be CBC for CBCMAC';<br> LIT_OUTFILE_OPEN_ERROR = LIT_COMPNAME + ': Could not open output file';<br> LIT_OUTFILE_WRITE_ERROR = LIT_COMPNAME + ': Error writing output file';<br> LIT_INPUT_LENGTH = LIT_COMPNAME + ': Input not valid - too short';<br> LIT_BASE64CNV = LIT_COMPNAME + ': Error converting from Base64 - invalid character';<br><br> DES_Data: array[0..7, 0..63] of LongWord = (<br> ($00200000,$04200002,$04000802,$00000000,$00000800,$04000802,$00200802,$04200800,<br> $04200802,$00200000,$00000000,$04000002,$00000002,$04000000,$04200002,$00000802,<br> $04000800,$00200802,$00200002,$04000800,$04000002,$04200000,$04200800,$00200002,<br> $04200000,$00000800,$00000802,$04200802,$00200800,$00000002,$04000000,$00200800,<br> $04000000,$00200800,$00200000,$04000802,$04000802,$04200002,$04200002,$00000002,<br> $00200002,$04000000,$04000800,$00200000,$04200800,$00000802,$00200802,$04200800,<br> $00000802,$04000002,$04200802,$04200000,$00200800,$00000000,$00000002,$04200802,<br> $00000000,$00200802,$04200000,$00000800,$04000002,$04000800,$00000800,$00200002),<br> ($00000100,$02080100,$02080000,$42000100,$00080000,$00000100,$40000000,$02080000,<br> $40080100,$00080000,$02000100,$40080100,$42000100,$42080000,$00080100,$40000000,<br> $02000000,$40080000,$40080000,$00000000,$40000100,$42080100,$42080100,$02000100,<br> $42080000,$40000100,$00000000,$42000000,$02080100,$02000000,$42000000,$00080100,<br> $00080000,$42000100,$00000100,$02000000,$40000000,$02080000,$42000100,$40080100,<br> $02000100,$40000000,$42080000,$02080100,$40080100,$00000100,$02000000,$42080000,<br> $42080100,$00080100,$42000000,$42080100,$02080000,$00000000,$40080000,$42000000,<br> $00080100,$02000100,$40000100,$00080000,$00000000,$40080000,$02080100,$40000100),<br> ($00000208,$08020200,$00000000,$08020008,$08000200,$00000000,$00020208,$08000200,<br> $00020008,$08000008,$08000008,$00020000,$08020208,$00020008,$08020000,$00000208,<br> $08000000,$00000008,$08020200,$00000200,$00020200,$08020000,$08020008,$00020208,<br> $08000208,$00020200,$00020000,$08000208,$00000008,$08020208,$00000200,$08000000,<br> $08020200,$08000000,$00020008,$00000208,$00020000,$08020200,$08000200,$00000000,<br> $00000200,$00020008,$08020208,$08000200,$08000008,$00000200,$00000000,$08020008,<br> $08000208,$00020000,$08000000,$08020208,$00000008,$00020208,$00020200,$08000008,<br> $08020000,$08000208,$00000208,$08020000,$00020208,$00000008,$08020008,$00020200),<br> ($01010400,$00000000,$00010000,$01010404,$01010004,$00010404,$00000004,$00010000,<br> $00000400,$01010400,$01010404,$00000400,$01000404,$01010004,$01000000,$00000004,<br> $00000404,$01000400,$01000400,$00010400,$00010400,$01010000,$01010000,$01000404,<br> $00010004,$01000004,$01000004,$00010004,$00000000,$00000404,$00010404,$01000000,<br> $00010000,$01010404,$00000004,$01010000,$01010400,$01000000,$01000000,$00000400,<br> $01010004,$00010000,$00010400,$01000004,$00000400,$00000004,$01000404,$00010404,<br> $01010404,$00010004,$01010000,$01000404,$01000004,$00000404,$00010404,$01010400,<br> $00000404,$01000400,$01000400,$00000000,$00010004,$00010400,$00000000,$01010004),<br> ($10001040,$00001000,$00040000,$10041040,$10000000,$10001040,$00000040,$10000000,<br> $00040040,$10040000,$10041040,$00041000,$10041000,$00041040,$00001000,$00000040,<br> $10040000,$10000040,$10001000,$00001040,$00041000,$00040040,$10040040,$10041000,<br> $00001040,$00000000,$00000000,$10040040,$10000040,$10001000,$00041040,$00040000,<br> $00041040,$00040000,$10041000,$00001000,$00000040,$10040040,$00001000,$00041040,<br> $10001000,$00000040,$10000040,$10040000,$10040040,$10000000,$00040000,$10001040,<br> $00000000,$10041040,$00040040,$10000040,$10040000,$10001000,$10001040,$00000000,<br> $10041040,$00041000,$00041000,$00001040,$00001040,$00040040,$10000000,$10041000),<br> ($20000010,$20400000,$00004000,$20404010,$20400000,$00000010,$20404010,$00400000,<br> $20004000,$00404010,$00400000,$20000010,$00400010,$20004000,$20000000,$00004010,<br> $00000000,$00400010,$20004010,$00004000,$00404000,$20004010,$00000010,$20400010,<br> $20400010,$00000000,$00404010,$20404000,$00004010,$00404000,$20404000,$20000000,<br> $20004000,$00000010,$20400010,$00404000,$20404010,$00400000,$00004010,$20000010,<br> $00400000,$20004000,$20000000,$00004010,$20000010,$20404010,$00404000,$20400000,<br> $00404010,$20404000,$00000000,$20400010,$00000010,$00004000,$20400000,$00404010,<br> $00004000,$00400010,$20004010,$00000000,$20404000,$20000000,$00400010,$20004010),<br> ($00802001,$00002081,$00002081,$00000080,$00802080,$00800081,$00800001,$00002001,<br> $00000000,$00802000,$00802000,$00802081,$00000081,$00000000,$00800080,$00800001,<br> $00000001,$00002000,$00800000,$00802001,$00000080,$00800000,$00002001,$00002080,<br> $00800081,$00000001,$00002080,$00800080,$00002000,$00802080,$00802081,$00000081,<br> $00800080,$00800001,$00802000,$00802081,$00000081,$00000000,$00000000,$00802000,<br> $00002080,$00800080,$00800081,$00000001,$00802001,$00002081,$00002081,$00000080,<br> $00802081,$00000081,$00000001,$00002000,$00800001,$00002001,$00802080,$00800081,<br> $00002001,$00002080,$00800000,$00802001,$00000080,$00800000,$00002000,$00802080),<br> ($80108020,$80008000,$00008000,$00108020,$00100000,$00000020,$80100020,$80008020,<br> $80000020,$80108020,$80108000,$80000000,$80008000,$00100000,$00000020,$80100020,<br> $00108000,$00100020,$80008020,$00000000,$80000000,$00008000,$00108020,$80100000,<br> $00100020,$80000020,$00000000,$00108000,$00008020,$80108000,$80100000,$00008020,<br> $00000000,$00108020,$80100020,$00100000,$80008020,$80100000,$80108000,$00008000,<br> $80100000,$80008000,$00000020,$80108020,$00108020,$00000020,$00008000,$80000000,<br> $00008020,$80108000,$00100000,$80000020,$00100020,$80008020,$80000020,$00100020,<br> $00108000,$00000000,$80008000,$00008020,$80000000,$80100020,$80108020,$00108000));<br><br> DES_PC1: array[0..55] of Byte =<br> (56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,<br> 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,<br> 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,<br> 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3);<br><br> DES_PC2: array[0..47] of Byte =<br> (13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,<br> 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,<br> 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,<br> 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31);<br><br><br>{*******************************************************************************<br>* Table : BinToAsc *<br>********************************************************************************<br>* Purpose : The encode table used by Base64 encoding *<br>*******************************************************************************}<br> BinToAsc : Array [0..63] of Char =<br> ('+', '-','0','1','2','3','4','5','6','7',<br> '8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',<br> 'P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d',<br> 'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s',<br> 't','u','v','w','x','y','z');<br><br>{$ifdef COMPONENT}<br>{*******************************************************************************<br>* Procedure : Register *<br>********************************************************************************<br>* Purpose : Declares the component to the Delhpi IDE (in component mode only)*<br>********************************************************************************<br>* Paramters : 'Crypto' : the name of the Tab under which the component should *<br>* appear *<br>* 'TDES' The name of the component in the tab. Must match the *<br>* declared type name *<br>********************************************************************************<br>* Returns : None *<br>*******************************************************************************}<br>procedure Register;<br>begin<br> RegisterComponents('Crypto', [TDES]);<br>end; {Register}<br>{$endif}<br><br>{*******************************************************************************<br>* Procedure : EncodeString *<br>********************************************************************************<br>* Purpose : Encodes the binary string into a base64 representation to avoid *<br>* problems with nulls in the encoded string *<br>********************************************************************************<br>* Paramters : Input - the string to be encoded *<br>********************************************************************************<br>* Returns : the encoded string *<br>*******************************************************************************}<br>function TDES.EncodeString(InputString: string): string;<br>var<br> Counter: integer;<br> ReturnString: string;<br> b: Byte;<br> i: integer;<br> last: byte;<br> Flush: Boolean;<br> LengthInput: integer;<br>begin<br> Counter := 0;<br> ReturnString := '';<br> Flush := False;<br> last := 0;<br><br> // deal with flushing the partial byte at the end of the string<br> if (Length(InputString) mod 3) <> 0 then<br> begin<br> InputString := InputString + Chr(0);<br> // flush controls the last byte mod 3<br> Flush := True;<br> end; {if}<br><br> LengthInput := Length(InputString);<br> i := 1;<br> while (i <= LengthInput) do<br> begin<br> if i <= LengthInput then<br> begin<br> b := Ord(InputString);<br> end<br> else<br> begin<br> b := 0;<br> end; {if}<br><br> case Counter of<br> 0:<br> begin<br> ReturnString := ReturnString + BinToAsc[(b shr 2)];<br> last := b;<br> end;<br> 1:<br> begin<br> ReturnString := ReturnString + BinToAsc[((last and $3) shl 4) or ((b and $F0) shr 4) ];<br> last := b;<br> end;<br> 2:<br> begin<br> ReturnString := ReturnString + BinToAsc[((last and $F) shl 2) or ((b and $C0) shr 6)];<br> if not (Flush and (i = LengthInput)) then<br> begin<br> ReturnString := ReturnString + BinToAsc[(b and $3F)];<br> end;<br> last := 0;<br> end;<br> end; {case}<br><br> Inc(Counter);<br> if Counter = 3 then<br> begin<br> Counter := 0;<br> end;<br><br> Inc(i);<br> end; {while}<br><br> Result := ReturnString;<br>end; {EncodeString}<br><br>{*******************************************************************************<br>* Procedure : DecodeString *<br>********************************************************************************<br>* Purpose : Decodes the binary string into a base64 representation to avoid *<br>* problems with nulls in the encoded string *<br>********************************************************************************<br>* Paramters : Input - the string to be decoded *<br>********************************************************************************<br>* Returns : the decoded string *<br>*******************************************************************************}<br>function TDES.DecodeString(InputString: string): string;<br> function DecodeBase64(b: byte): byte;<br> {*******************************************************************************<br> * Procedure : DecodeBase64 *<br> ********************************************************************************<br> * Purpose : Decodes a byte from the Base64 string *<br> ********************************************************************************<br> * Paramters : b - the byte to be decoded *<br> ********************************************************************************<br> * Returns : the decoded byte *<br> *******************************************************************************}<br> begin<br> if (b >= Ord('0')) and (b <= Ord('9')) then<br> begin<br> Result := b - Ord('0') + 2;<br> Exit;<br> end;<br> if (b >= Ord('A')) and (b <= Ord('Z')) then<br> begin<br> Result := b - Ord('A') + 12;<br> Exit;<br> end;<br> if (b >= Ord('a')) and (b <= Ord('z')) then<br> begin<br> Result := b - Ord('a') + 38;<br> Exit;<br> end;<br> if b = Ord('+') then<br> begin<br> Result := 0;<br> Exit;<br> end;<br> if b = Ord('-') then<br> begin<br> Result := 1;<br> Exit;<br> end;<br><br> // Default result if the char is not recognised<br> raise EConvertError.Create(LIT_BASE64CNV);<br> end; {DecodeBase64}<br>var<br> Counter: integer;<br> ReturnString: string;<br> c: Char;<br> last: byte;<br> this: byte;<br> i: integer;<br>begin<br> Counter := 0;<br> ReturnString := '';<br> last := 0;<br><br> for i := 1 to Length(InputString) do<br> begin<br> c := InputString;<br> case Counter of<br> 0:<br> begin<br> last := DecodeBase64(Ord(c)) shl 2;<br> end;<br> 1:<br> begin<br> this := DecodeBase64(Ord(c));<br> ReturnString := ReturnString + Chr((last or (this shr 4)) and $ff);<br> last := this shl 4;<br> end;<br> 2:<br> begin<br> this := DecodeBase64(Ord(c));<br> ReturnString := ReturnString + Chr((last or (this shr 2)) and $ff);<br> last := this shl 6;<br> end;<br> 3:<br> begin<br> this := DecodeBase64(Ord(c));<br> ReturnString := ReturnString + Chr((last or this) and $ff);<br> last := 0;<br> end;<br> end; {case}<br><br> Inc(Counter);<br> if Counter = 4 then<br> begin<br> Counter := 0;<br> end; {if}<br> end; {for}<br><br> Result := ReturnString;<br>end; {DecodeString}<br><br>{*******************************************************************************<br>* Procedure : GetVersion *<br>********************************************************************************<br>* Purpose : Returns the internal version number of the component *<br>********************************************************************************<br>* Paramters : None *<br>********************************************************************************<br>* Returns : String - the version number expressed as a string *<br>*******************************************************************************}<br>function TDES.GetVersion;<br>begin<br> // return the version string<br> Result := LIT_COMPNAME + ' ' + RELVER;<br><br> {$ifdef REGISTERED}<br> Result := Result + ' Registered';<br> {$endif}<br> {$ifdef NOTREGISTERED}<br> Result := Result + ' Unregistered';<br> {$endif}<br> {$ifdef FREEWARE}<br> Result := Result + ' Freeware';<br> {$endif}<br>end; {GetVersion}<br><br>{$ifndef COMPONENT}<br>{*******************************************************************************<br>* Procedure : SetCipherMode *<br>********************************************************************************<br>* Purpose : Sets the ciphermode when defined as an object *<br>********************************************************************************<br>* Paramters : 'Value' : The new cipher mode to be set *<br>********************************************************************************<br>* Returns : None *<br>*******************************************************************************}<br>procedure TDES.SetCipherMode(const Value: TCipherMode);<br>begin<br> FCipherMode := Value;<br>end; {SetCipherMode}<br>{$endif}<br><br>{*******************************************************************************<br>* Procedure : InitialiseString *<br>********************************************************************************<br>* Purpose : Loads the passphrase into the context block *<br>********************************************************************************<br>* Paramters : 'Key' - the string which holds the key *<br>********************************************************************************<br>* Returns : None *<br>*******************************************************************************}<br>procedure TDES.InitialiseString(const Key: string);<br>var<br> KeyArray: TBlock;<br> i: integer;<br>begin<br> // clear the context<br> FillChar(ctx.ct, Sizeof(ctx.ct), #0);<br> FillChar(ctx.ByteBuffer, Sizeof(ctx.ByteBuffer), #0);<br> FillChar(KeyArray, Sizeof(KeyArray), #0);<br><br> {**************************************************************************<br> ************ This section of code implements the 64 bit limit *************<br> ************ imposed by the Wassennar agreement. The key is *************<br> ************ limited to 64 bits. Should you be in a country *************<br> ************ where the Wassennar agreement is not in force, *************<br> ************ undefine the WASSENAAR_LIMITED variable. *************<br> **************************************************************************}<br><br> {$ifdef WASSENAAR_LIMITED}<br> // turn the key string into a key array<br> for i := 1 to Length(Key) do<br> begin<br> KeyArray[(i-1) mod 8] := Ord(Key);<br> end; {for}<br> {$else}<br> // turn the key string into a key array<br> for i := 1 to Length(Key) do<br> begin<br> KeyArray[(i-1) mod 8] := Ord(Key);<br> end; {for}<br> {$endif}<br> // and perform the initialisation with the concatenated string<br> DES_Core_Key_Setup(KeyArray);<br><br> // mark the context as initialised<br> ctx.KeyInit := True;<br>end; {InitialiseString}<br><br>{*******************************************************************************<br>* Procedure : InitialiseByte *<br>********************************************************************************<br>* Purpose : Loads the passphrase into the context block *<br>********************************************************************************<br>* Paramters : 'Key' - array of bytes which holds the key *<br>* 'KeyLength' - the number of bytes in the array which are to be *<br>* read to load the key - need not be the same as the length of the *<br>* array *<br>********************************************************************************<br>* Returns : 'OK' if the operation was a success, otherwise an error code *<br>*******************************************************************************}<br>procedure TDES.InitialiseByte(const Key: array of Byte; KeyLength: integer);<br>var<br> KeyArray: TBlock;<br> i: integer;<br>begin<br> // clear the context<br> FillChar(ctx.ct, Sizeof(ctx.ct), #0);<br> FillChar(ctx.ByteBuffer, Sizeof(ctx.ByteBuffer), #0);<br> FillChar(KeyArray, Sizeof(KeyArray), #0);<br><br> {**************************************************************************<br> ************ This section of code implements the 64 bit limit *************<br> ************ imposed by the Wassennar agreement. The key is *************<br> ************ limited to 64 bits. Should you be in a country *************<br> ************ where the Wassennar agreement is not in force, *************<br> ************ undefine the WASSENAAR_LIMITED variable. *************<br> **************************************************************************}<br><br> {$ifdef WASSENAAR_LIMITED}<br> // buffer the passed key into the key array to make sure that<br> // it is padded with something defined (just in case)<br> for i := 0 to KeyLength-1 do<br> begin<br> KeyArray[i mod 8] := Key;<br> end; {for}<br> {$else}<br> // buffer the passed key into the key array to make sure that<br> // it is padded with something defined (just in case)<br> for i := 0 to KeyLength-1 do<br> begin<br> KeyArray[i mod 8] := Key;<br> end; {for}<br> {$endif}<br><br> // and perform the initialisation with the concatenated string<br> DES_Core_Key_Setup(KeyArray);<br><br> // mark the context as initialised<br> ctx.KeyInit := True;<br>end; {InitialiseByte}<br><br>{*******************************************************************************<br>* Procedure : LoadIVString *<br>********************************************************************************<br>* Purpose : Loads the Initialisation Vector *<br>* Note: this is only necessary for modes other than ECB *<br>********************************************************************************<br>* Paramters : 'IVString' - the string which holds the IV to be set *<br>********************************************************************************<br>* Returns : None - (Null IVs are also valid) *<br>*******************************************************************************}<br>procedure TDES.LoadIVString(Const IVString: string);<br>var<br> i: integer;<br>begin<br> // clear the IV in the context<br> FillChar(ctx.IV, BLOCKSIZE, #0);<br><br> // wrap the IV string into the 16 bytes of the IV block using xor<br> for i := 1 to Length(IVString) do<br> begin<br> ctx.IV[(i-1) and (BLOCKSIZE - 1)] := ctx.IV[(i-1) and (BLOCKSIZE - 1)] xor Ord(IVString);<br> end; {for i}<br><br> // mark the IV as being initialised<br> ctx.IVInit := True;<br>end; {LoadIVString}<br><br>{*******************************************************************************<br>* Procedure : LoadIVByte *<br>********************************************************************************<br>* Purpose : Loads the Initialisation Vector *<br>* Note: this is only necessary for modes other than ECB *<br>********************************************************************************<br>* Paramters : 'IVByte' - the array of bytes which holds the IV to be set *<br>********************************************************************************<br>* Returns : None - (Null IVs are also valid) *<br>*******************************************************************************}<br>procedure TDES.LoadIVByte(const IVByte: array of Byte; IVLength: integer);<br>var<br> i: integer;<br>begin<br> // clear the IV in the context<br> FillChar(ctx.ByteBuffer, BLOCKSIZE, #0);<br><br> // wrap the IV string into the 8 bytes of the IV block using xor<br> for i := 1 to IVLength do<br> begin<br> ctx.ByteBuffer[(i-1) and (BLOCKSIZE - 1)] := ctx.ByteBuffer[(i-1) and (BLOCKSIZE - 1)] xor IVByte;<br> end; {for i}<br><br> // mark the IV as being initialised<br> ctx.IVInit := True;<br>end; {LoadIVByte}<br><br>{*******************************************************************************<br>* Procedure : EncryptBlock *<br>********************************************************************************<br>* Purpose : Encrypts the contents of the block usint the key (and possibly *<br>* the IV) previously set. *<br>********************************************************************************<br>* Paramters : 'Input' the block to be encrypted *<br>* : 'Output' the encrypted block *<br>********************************************************************************<br>* Returns : OK if successful, otherwise error code *<br>*******************************************************************************}<br>procedure TDES.EncBlock(const Input: TBlock; var Output: TBlock);<br>begin<br> // check that we have a keys and IV<br> CheckKeys;<br><br> // copy the input to the context blockbuffer<br> ctx.ByteBuffer := Input;<br><br> // perform the encryption on the context<br> EncryptBlockMode;<br><br> // copy the context back to the blockbuffer<br> Output := ctx.ByteBuffer;<br>end; {EncryptBlock}<br><br>{*******************************************************************************<br>* Procedure : DecryptBlock *<br>********************************************************************************<br>* Purpose : Decrypts the contents of the block usint the key (and possibly *<br>* the IV) previously set. *<br>********************************************************************************<br>* Paramters : 'Input' the encrypted block to be decrypted *<br>* : 'Output' the decrypted block *<br>********************************************************************************<br>* Returns : OK if successful, otherwise error code *<br>*******************************************************************************}<br>procedure TDES.DecBlock(const Input: TBlock; var Output: TBlock);<br>begin<br> // check that we have a keys and IV<br> CheckKeys;<br><br> // copy the input to the context blockbuffer<br> ctx.ByteBuffer := Input;<br><br> // perform the decryption<br> DecryptBlockMode;<br><br> // copy the context back to the blockbuffer<br> Output := ctx.ByteBuffer;<br>end; {DecryptBlock}<br><br>{*******************************************************************************<br>* Procedure : EncryptBuffer *<br>********************************************************************************<br>* Purpose : Encrypts the contents of the buffer using the key (and possibly *<br>* the IV) previously set. Does not take care of any padding. *<br>********************************************************************************<br>* Paramters : 'Len' the number of bytes in the buffer *<br>********************************************************************************<br>* Returns : OK if successful, otherwise error code *<br>*******************************************************************************}<br>procedure TDES.EncryptBuffer(const Len: integer);<br>var<br> Index: integer;<br>begin<br> // check that we have a keys and IV<br> CheckKeys;<br><br> // index is the pointer to the current position in the buffer<br> Index := 0;<br><br> // PtrBuffer points to the address of the buffer<br> PtrBuffer := @FBuffer;<br><br> // for every block in the buffer<br> repeat<br> // move one block from the buffer contents into the context<br> Move(FBuffer[Index], ctx.ByteBuffer, BLOCKSIZE);<br><br> // encrypt the context<br> EncryptBlockMode;<br><br> // move the block back<br> Move(ctx.ByteBuffer, PtrBuffer^[Index], BLOCKSIZE);<br><br> // increment the pointer<br> Inc(Index,BLOCKSIZE);<br> until Index = Len;<br>end; {EncryptBuffer}<br><br>{*******************************************************************************<br>* Procedure : DecryptBuffer *<br>********************************************************************************<br>* Purpose : Decrypts the contents of the buffer usint the key (and possibly *<br>* the IV) previously set. *<br>********************************************************************************<br>* Paramters : 'Len' the number of bytes in the buffer *<br>********************************************************************************<br>* Returns : OK if successful, otherwise error code *<br>*******************************************************************************}<br>procedure TDES.DecryptBuffer(const Len: integer);<br>var<br> Index: integer;<br>begin<br> // check that we have a keys and IV<br> CheckKeys;<br><br> // index is the pointer to the current position in the buffer<br> Index := 0;<br><br> // PtrBuffer points to the address of the buffer<br> PtrBuffer := @FBuffer;<br><br> // for every block in the buffer<br> //XuYe 2001.6.12<br> {repeat}<br> while Index < Len do<br> begin<br> // move one block from the buffer contents into the context<br> Move(FBuffer[Index], ctx.ByteBuffer, BLOCKSIZE);<br><br> // decrypt the context<br> DecryptBlockMode;<br><br> // move the block back<br> Move(ctx.ByteBuffer, PtrBuffer^[Index], BLOCKSIZE);<br><br> // increment the pointer<br> Inc(Index,BLOCKSIZE);<br> end;<br> {until Index = Len;}<br> end; {DecryptBuffer}<br><br>{*******************************************************************************<br>* Procedure : EncryptFile *<br>********************************************************************************<br>* Purpose : Encrypts InputFile to OutputFile using the Key (and possibly *<br>* the IV) previously set. *<br>********************************************************************************<br>* Paramters : 'InputFileName' the plaintext file *<br>* 'OutputFileName' the ciphertext file *<br>********************************************************************************<br>* Returns : OK if successful, otherwise error code *<br>*******************************************************************************}<br>procedure TDES.EncFile(const InputFileName: string; OutputFileName: string);<br>var<br> InputFile, OutputFile: File;<br> NumWrite, NumRead: integer;<br> Pad: integer;<br> Index: integer;<br>begin<br> // check that we have a keys and IV<br> CheckKeys;<br><br> // open the input file<br> try<br> AssignFile(InputFile, InputFileName);<br> except<br> // we could not open the input file for some reason<br> // so exit gracefully with an error code<br> raise EFileError.Create(LIT_INFILE_NOT_FOUND);<br> Exit;<br> end;<br><br> // reset the input file<br> FileMode := 0;<br> Reset(InputFile, 1);<br><br> // open the output file<br> try<br> AssignFile(OutputFile, OutputFileName);<br> except<br> // we could not open the output file for some reason<br> // so exit gracefully with an error code<br> raise EFileError.Create(LIT_OUTFILE_OPEN_ERROR);<br> Exit;<br> end;<br><br> // reset the output file for writing<br> Rewrite(OutputFile, 1);<br><br> // this is the main loop of EncryptFile. We read (for performance reasons) a block<br> // at a time and encrypt the block. This minimises the accesses to the disk<br> repeat<br> // Read an input block<br> BlockRead(InputFile,FBuffer,BUFFERSIZE, NumRead);<br><br> //Pad the input to a multiple of 64bits(8BYTES) with Nulls at the end of the file<br> if EOF(InputFile) then<br> begin<br> // pad the last block<br> // if we have a zero padding, expand this to a full 8 byte block<br> Pad := BLOCKSIZE - (NumRead mod BLOCKSIZE);<br> Index := Pad;<br><br> // add the pad bytes to the buffer<br> while Index <> 0 do<br> begin<br> FBuffer[NumRead] := Pad;<br> Inc(NumRead);<br> Dec(Index);<br> end; {while Index}<br> end; {if EOF}<br><br> // encrypt the buffer<br> EncryptBuffer(NumRead);<br><br> // write the block to the output file<br> BlockWrite(OutputFile, FBuffer, NumRead, NumWrite);<br><br> // if NumRead <> NumWrite, it is probable that the disk is full<br> if NumRead <> NumWrite then<br> begin<br> // there was an error writing the output file<br> // exit with the error code<br> raise EFileError.Create(LIT_OUTFILE_WRITE_ERROR);<br> Exit;<br> end; {if NumRead <> NumWrite}<br> until EOF(InputFile) or (NumWrite <> NumRead); {repeat}<br><br> // close the files<br> CloseFile(InputFile);<br> CloseFile(OutputFile);<br>end; {EncryptFile}<br>