Шифрование и дешифрование текстов по принципу S-Coder со скрытым ключом
01.01.2007
{ **** UBPFD *********** by kladovka.net.ru **** >> Шифрование и дешифрование текстов по принципу S-Coder со скрытым ключом После прменения выполнения функции Encrypt с входным исходным текстом, результат будет иметь символы в диапазоне от 0 - 255 в ASCII таблице, следовательно если вам надо сохранить где либо шифровку, то лучше преобразовать в числовой вид - 16разрядный hex из ASCII таблицы (функция Write) Зависимости: Windows, SysUtils Автор: Yuri Btr, btr1978@rambler.ru, ICQ:125988632, Керчь Copyright: EFD Systems http://www.mindspring.com/~efd Дата: 23 мая 2002 г. ********************************************** } procedure EnCipher(var Source:AnsiString); {Low order, 7-bit ASCII (char. 32-127) encryption designed for database use. Control and high order (8 bit) characters are passed through unchanged. Uses a hybrid method...random table substitution with bit-mangled output. No passwords to worry with (the built-in table is the password). Not industrial strength but enough to deter the casual hacker or snoop. Even repeating char. sequences have little discernable pattern once encrypted. NOTE: When displaying encrypted strings, remember that some characters within the output range are interpreted by VCL components; for example, '&'.} asm Push ESI //Save the good stuff Push EDI Or EAX,EAX Jz @Done Push EAX Call UniqueString Pop EAX Mov ESI,[EAX] //String address into ESI Or ESI,ESI Jz @Done Mov ECX,[ESI-4] //String Length into ECX Jecxz @Done //Abort on null string Mov EDX,ECX //initialize EDX with length Lea EDI,@ECTbl //Table address into EDI Cld //make sure we go forward @L1: Xor EAX,EAX Lodsb //Load a byte from string Sub AX,32 //Adjust to zero base Js @Next //Ignore if control char. Cmp AX,95 Jg @Next //Ignore if high order char. Mov AL,[EDI+EAX] //get the table value Test CX,3 //screw it up some Jz @L2 Rol EDX,3 @L2: And DL,31 Xor AL,DL Add EDX,ECX Add EDX,EAX Add AL,32 //adjust to output range Mov [ESI-1],AL //write it back into string @Next: Dec ECX Jnz @L1 // Loop @L1 //do it again if necessary @Done: Pop EDI Pop ESI Jmp @Exit // Ret //this does not work with Delphi 3 - EFD 971022 @ECTbl: //The encipher table DB 75,85,86,92,93,95,74,76,84,87,91,94 DB 63,73,77,83,88,90,62,64,72,78,82,89 DB 51,61,65,71,79,81,50,52,60,66,70,80 DB 39,49,53,59,67,69,38,40,48,54,58,68 DB 27,37,41,47,55,57,26,28,36,42,46,56 DB 15,25,29,35,43,45,14,16,24,30,34,44 DB 06,13,17,23,31,33,05,07,12,18,22,32 DB 01,04,08,11,19,21,00,02,03,09,10,20 @Exit: end; procedure DeCipher(var Source:AnsiString); {Decrypts a string previously encrypted with EnCipher.} asm Push ESI //Save the good stuff Push EDI Push EBX Or EAX,EAX Jz @Done Push EAX Call UniqueString Pop EAX Mov ESI,[EAX] //String address into ESI Or ESI,ESI Jz @Done Mov ECX,[ESI-4] //String Length into ECX Jecxz @Done //Abort on null string Mov EDX,ECX //Initialize EDX with length Lea EDI,@DCTbl //Table address into EDI Cld //make sure we go forward @L1: Xor EAX,EAX Lodsb //Load a byte from string Sub AX,32 //Adjust to zero base Js @Next //Ignore if control char. Cmp AX,95 Jg @Next //Ignore if high order char. Mov EBX,EAX //save to accumulate below Test CX,3 //unscrew it Jz @L2 Rol EDX,3 @L2: And DL,31 Xor AL,DL Add EDX,ECX Add EDX,EBX Mov AL,[EDI+EAX] //get the table value Add AL,32 //adjust to output range Mov [ESI-1],AL //store it back in string @Next: Dec ECX Jnz @L1 // Loop @L1 //do it again if necessary @Done: Pop EBX Pop EDI Pop ESI Jmp @Exit // Ret Does not work with Delphi3 - EFD 971022 @DCTbl: //The decryption table DB 90,84,91,92,85,78,72,79,86,93,94,87 DB 80,73,66,60,67,74,81,88,95,89,82,75 DB 68,61,54,48,55,62,69,76,83,77,70,63 DB 56,49,42,36,43,50,57,64,71,65,58,51 DB 44,37,30,24,31,38,45,52,59,53,46,39 DB 32,25,18,12,19,26,33,40,47,41,34,27 DB 20,13,06,00,07,14,21,28,35,29,22,15 DB 08,01,02,09,16,23,17,10,03,04,11,05 @Exit: end; procedure Crypt(var Source:Ansistring;const Key:AnsiString); {Encrypt AND decrypt strings using an enhanced XOR technique similar to S-Coder (DDJ, Jan. 1990). To decrypt, simply re-apply the procedure using the same password key. This algorithm is reasonably secure on it's own; however,there are steps you can take to make it even more secure. 1) Use a long key that is not easily guessed. 2) Double or triple encrypt the string using different keys. To decrypt, re-apply the passwords in reverse order. 3) Use EnCipher before using Crypt. To decrypt, re-apply Crypt first then use DeCipher. 4) Some unique combination of the above NOTE: The resultant string may contain any character, 0..255.} asm Push ESI //Save the good stuff Push EDI Push EBX Or EAX,EAX Jz @Done Push EAX Push EDX Call UniqueString Pop EDX Pop EAX Mov EDI,[EAX] //String address into EDI Or EDI,EDI Jz @Done Mov ECX,[EDI-4] //String Length into ECX Jecxz @Done //Abort on null string Mov ESI,EDX //Key address into ESI Or ESI,ESI Jz @Done Mov EDX,[ESI-4] //Key Length into EDX Dec EDX //make zero based Js @Done //abort if zero key length Mov EBX,EDX //use EBX for rotation offset Mov AH,DL //seed with key length Cld //make sure we go forward @L1: Test AH,8 //build stream char. Jnz @L3 Xor AH,1 @L3: Not AH Ror AH,1 Mov AL,[ESI+EBX] //Get next char. from Key Xor AL,AH //XOR key with stream to make pseudo-key Xor AL,[EDI] //XOR pseudo-key with Source Stosb //store it back Dec EBX //less than zero ? Jns @L2 //no, then skip Mov EBX,EDX //re-initialize Key offset @L2: Dec ECX Jnz @L1 @Done: Pop EBX //restore the world Pop EDI Pop ESI end; function Encrypt(text:Ansistring):Ansistring; //Это прсто интерфейс функций EnCipher и Crypt для шифрования строки текста begin {шифруем текст} EnCipher(Text); {зашифровываем ключом в Edit1} Crypt(Text,Form1.Edit1.Text); Result:=Text; end; function Decrypt(text:Ansistring):Ansistring; //Это прсто интерфейс функций EnCipher и Crypt для дешифрования строки текста begin begin {расшифровываем ключом в Edit1} Crypt(Text,Form1.Edit1.Text); {расшифровываем результат} DeCipher(Text); Result:=Text; end; function Write(text:Ansistring):Ansistring; var i:integer; begin Result:=''; For i:=1 to Length(text) do {получаем hex код из текста} Result:=Result+InttoHex(ord(text[i]),2); end; function Read(text:Ansistring):Ansistring; var i:integer; begin Result:=''; For I:=1 to Length(text) do if odd(i) then {получаем текст из hex кода} Result:=Result+Chr(StrtoInt('$'+text[i]+text[i+1])); end;
Пример использования:
функции вставляем после Implementation
и после {$R *.dfm}
В программе пишем просто:
procedure TForm1.Button1Click(Sender: TObject); begin {Задайте здесь ваш секретный ключ} Edit1.text:='My special hidden key'; {Шифруем и преобразовываем тест в Memo1 и заносим результат в Memo2} Memo2.text:=Write(Encrypt(Memo1.text)); {Дешифруем и преобразовываем тест в Memo2 и заносим результат в Memo3} Memo3.text:=Decrypt(Read(Memo2.text));)); end;