Entwickler-Ecke

Open Source Units - Vigenere Verschlüsselung als Unit


Maweki - Fr 17.09.04 22:28
Titel: Vigenere Verschlüsselung als Unit
Hallo[meta]Vigenere Verschlüsselung Unit Delphi Pascal[/meta]

hab vor einiger Zeit mal eine Unit gecodet, die Vigenere verschlüsselt. Also Polyalphabetisch mit Schlüsselwort.

Ich dachte, es könnte jemanden interessieren...


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
                {**********************}
                {     Master_Fixel     }
                {          u.          }
                {        Maweki        }
                {         2004         }
                {**********************}
      //    Die Funktionen Crypt und EnCrypt    \\
     //     geben als Result den ver- oder       \\
    //       entschlüsselten Text zurück          \\
unit Vignere;

interface
  function Crypt(Key: String; Text: String): String;
  function EnCrypt(Key: String; Text: String): String;

implementation

var
  Liste: Array of Array of Char;
  Filled: Boolean;

Procedure Fill;
const
  Alphabet : array[0..25of Char =
    ('A''B''C''D''E''F''G''H''I''J''K''L''M',
     'N''O''P''Q''R''S''T''U''V''W''X''Y''Z');
var
  i1, i2: Byte;
begin
  SetLength(Liste, 2626);
  for i1 := 0 to 25 do
    for i2 := 0 to 25 do
    begin
      if i1 + i2 > 25 then
        Liste[i1, i2] := Alphabet[i1 + i2 - 26]
      else
        Liste[i1, i2] := Alphabet[i1 + i2];
    end;
  Filled := true;
end;

function Crypt(Key: String; Text: String): String;
var
  i, x: Cardinal;
  i2, i3, x2, Rest: Byte;
  Z: ^Char;
begin
  if filled = false then
    Fill;
  x := Length(Text);
  x2 := Length(Key);
  for i := 1 to x do
  begin
    if not (Text[i] in ['A'..'Z''a'..'z']) then
      Continue;
    Z := @Text[i];
    Rest := i mod x2;
    i2 := Ord(Z^) - 65;
    if Rest = 0 then
      i3 := Ord(Key[x2]) - 65
    else
      i3 := Ord(Key[Rest]) - 65;
    if Ord(Z^) > 90 then
      Z^ := Chr(Ord(Liste[i2 - 32, i3]) + 32)
    else
      Z^ := Liste[i2, i3];
  end;
  Result := Text;
end;

function EnCrypt(Key: String; Text: String): String;
var
  i, x: Cardinal;
  i2, i3, Rest, x2: Byte;
  ZwChar: Char;
  C, D: ^Char;
  klein: Boolean;
begin
  if filled = false then
    Fill;
  x := Length(Text);
  x2 := Length(Key);
  for i := 1 to x do
  begin
    if not (Text[i] in ['A'..'Z''a'..'z']) then
      Continue;
    C := @Text[i];
    rest := i mod x2;
    if Rest = 0 then
      i3 := Ord(Key[x2]) - 65
    else
      i3 := Ord(Key[Rest]) - 65;
    ZwChar  := Liste[0, i3];
    i2 := 1;
    if Ord(C^) > 90 then
    begin
      klein := true;
      D^ := Chr(Ord(C^) - 32);
    end
    else
    begin
      klein := false;
      D^ := C^;
    end;

    if D^ <> Liste[0, i3] then
      while ZwChar <> D^ do
      begin
        ZwChar := Liste[i2, i3];
        Inc(i2);
      end;
    C^ := Liste[i2 - 10];
    if klein = true then
      C^ := Chr(Ord(C^) + 32);
  end;
  Result := Text;
end;

end.


Habs nich auskommentiert, sollte aber mehr oder weniger durchsichtig sein...


raziel - Sa 18.09.04 10:33

Habs mir jetzt weder weiter angeschaut, noch ausprobiert (grad kein Delphi zur Hand) aber ein kurzes Wort zur Terminologie:
Verschlüsselungsroutinen nennt man für gewöhnlich "Encrypt" und Entschlüsselungsroutinen "Decrypt". Zwei Funktionen "Crypt" und "EnCrypt", die ver- bzw. entschlüsseln zu nennen, ist etwas irreführend.

raziel


Maweki - Sa 18.09.04 12:30

sicher das encrypt verschlüsseln heisst?

Na gut, ok...

aber ich hab versucht, mich so gut wie es geht an den Styleguide zu halten...

http://de.wikipedia.org/wiki/Polyalphabetische_Substitution

da wird das Verfahren beschrieben. Habe es letztes Jahr an zwei Nachmittagen mit (meiner Meinung nach) recht guter Performance umgesetzt. Zum Texte verschlüsseln (Passwörter, was auch immer) ist es recht gut.
Und wenn der Schlüssel länger ist, als der zu verschlüsselnde Text, ist es ohne Schlüssel nicht knackbar...
naja, vielleicht interessierts ja wen...


JayEff - Mo 01.11.04 21:59

Ich muss dir leider sagen: wenn der schlüssel solange wie der Text ist, und nicht komplett zufällig ist, dann kann man auch das entschlüsseln. der Schlüssel muss komplett Zufallsgeneriert sein. noch ein tipp: nimm nicht das wort Crypt, sonder Code.
Encode: Verschlüsseln
Decode: Entschlüsseln. so hab ichs gemacht :D das finde ich sehr übersichtlich. ich hab auch sowas gemacht aber das lief nicht auf der Buchstaben ebene sondern auf der Byteebene...
ergebnisbuchstabe:=Char(Byte(ord(text[i])+(ord(schluessel[i]))); so ganz grob.

PS: Ja, Encode/-crypt ist mit sicherheit verschlüsseln.


Softchaos67 - Do 28.04.05 16:17

Hallo,
hab die Unit ausprobiert, leider funzt das Decode nicht.
Steigt immer mit einer Schutzverletzug aus.
Woran könnte das liegen?

Delphi-Quelltext
1:
2:
3:
4:
    begin
      klein := true;
      D^ := Chr(Ord(C^) - 32);  //hier knallts
    end


key =asdfghjkl
Text =ok

Encode klappt.
Danke
Matthias


Maweki - Sa 30.04.05 11:27

Das weiss ich leider auch nicht. Aber das Problem laesst sich loesen, indem man den entsprechenden Char-Pointer direkt durch einen Char ersetzt...


Softchaos67 - Mo 02.05.05 15:20

ok,
als char funktionierts.
Lassen sich mit diesem Verfahren auch Sonderzeichen verschlüsseln?
Bei $ kommt scheinbar immer $ zurück.
Muss ich noch irgendwas beachten?


Maweki - Mo 02.05.05 17:04

ich habe nur einen Buchstabenarray gemacht. Aber du muesstest meiner Meinung nach, den Array um die entsprechenden Zeichen in der richtigen Reihenfolge erweitern. Also du muesstest einen Array von allen vorhandenen Zeichen machen, in der Reihenfolge ihrer ANSI-Nummern und natuerlich diese Codestelle rausnehmen:

Delphi-Quelltext
1:
2:
if not (Text[i] in ['A'..'Z''a'..'z']) then  
      Continue;
Und auch die gross-klein-Umwandlung koennte etwas komische ergebnisse bekommen. Da musst du mal schauen, dass du fuer nicht-buchstaben keine gross-klein-abfrage machst.

Gruesse
Maweki


DarthDestroyer - Do 09.06.05 12:45

HUHU...

mein erster Beitrag ^^

Also... nun zu meiner Frage!

Was zum henker meint ihr mit (Char-Pointer direkt durch einen Char ersetzen)???

Ich programmiere schon seit einer halben ewigkeit und mache das auch in der Schule. Ich möchte jetzt ein Programm schreiben, was Dateien (die man im Internet hat) runterläd. Diese Daten sollen in einer Datei verschlüsselt aufbewahrt werden, dass man an diese URLs nur mit DEM Programm kommt!

Das Encode funzt! Aber beim Decode stürzt es eben immer wieder an der oben genannten Stelle ab!

Programmiere seit rund 4 Jahren mit VB, durch meine Schule wurde ich zu Delphi (gezwungen) überredet... Nach anfänglichen schwierigkeiten bei der eingewöhnung flutscht es jetzt! Nur aus dem Comment zu dem Quelltext werde ich nicht schlau...

Vielleicht könnte mir auch jemand helfen!

zB. welche Download-variante ich nutzen soll... oder sollte... usw...


MfG

DarthDestroyer

Moderiert von user profile iconNarses: überflüssige Leerzeilen entfernt


Nico Haase - Di 12.07.05 11:57

Für die Verschlüsslung könnte ich folgenden Code anbieten, der ohne das riesige Array auskommt:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
function verschluessle(inhalt, key: string): string;
var neu: char;
 zaehler, pos, verschiebung : integer;
begin
 inhalt := lowercase ( inhalt );
 key := lowercase ( key );
 result:= '';

 for zaehler := 1 to length ( inhalt ) do
  begin
   pos := zaehler mod length ( key );
    // suche die position im key raus, mit der aktuell verschlüsselt
    // werden soll
   if ( pos = 0 ) then pos := length ( key );
    // mod liefert 0 zurück, wenn die letzte position des keys erreicht ist

   verschiebung := ord ( key[pos] ) - 97;
    // verschiebung berechnen
    //   --> -97 ist nötig, da 97 das kleine a ist

   neu := chr ( ord ( inhalt[zaehler] ) + verschiebung );
    // erst den ascii-wert des aktuellen buchstaben rausfinden,
    // dann verschieben und aus ascii den buchstaben bilden

   if ( ord ( neu ) > 122 ) then
    neu := chr ( ord ( neu ) - 26 );
    // wenn der ascii-wert über 122 liegt, müssen 26 stellen abgezogen
    // werden, damit das ergebnis im bereich der kleinen buchstaben liegt

   result := result + neu;
  end;
end;


Sollte klappen ;)
mfg
Nico


F.Art - Mo 26.09.05 19:13

Ich finde diese Unit sehr interessant, leider habe ich auch das Problem das er beim entschlüsseln hängen bleibt. Und mir wäre es lieb wenn der Code so wäre das er alle Zeichen verwenden würde die der PC anbietet. Leider habe ich nicht viel Plan und schaffe es nicht selber. Vieleicht hat Jemand ja die fertige Unit für mich?


Maweki - Mo 26.09.05 22:50

ich habe die Menschliche Vorgehensweise implimentiert, fuer die Benutzung aller 255 Zeichen solltest du eine mathematische Buchstabenverschiebung anwenden, anstatt ein Quadrat...

hierfuer noetig sind eigentlich nur die Funktionen chr() und ord()...

Gruesse
Maweki


rizla - Mo 05.06.06 20:21
Titel: "de-vigenere"
hola
habe mal nen tool geschrieben, um vig zu knacken, bei bedarf pn oder icq.
:rizla:


Nowo - Sa 11.10.08 19:23

Ich weis, blöd das ich den Threat aufgreifen muss
aber ich wollte auch keine Mini threats erstellen.

Nico Haase hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
function verschluessle(inhalt, key: string): string;
var neu: char;
 zaehler, pos, verschiebung : integer;
begin
 inhalt := lowercase ( inhalt );
 key := lowercase ( key );
 result:= '';

 for zaehler := 1 to length ( inhalt ) do
  begin
   pos := zaehler mod length ( key );
    // suche die position im key raus, mit der aktuell verschlüsselt
    // werden soll
   if ( pos = 0 ) then pos := length ( key );
    // mod liefert 0 zurück, wenn die letzte position des keys erreicht ist
   verschiebung := ord ( key[pos] ) - 97;
    // verschiebung berechnen
    //   --> -97 ist nötig, da 97 das kleine a ist
   neu := chr ( ord ( inhalt[zaehler] ) + verschiebung );
    // erst den ascii-wert des aktuellen buchstaben rausfinden,
    // dann verschieben und aus ascii den buchstaben bilden
   if ( ord ( neu ) > 122 ) then
    neu := chr ( ord ( neu ) - 26 );
    // wenn der ascii-wert über 122 liegt, müssen 26 stellen abgezogen
    // werden, damit das ergebnis im bereich der kleinen buchstaben liegt
   result := result + neu;
  end;
end;


Aber wie ENTschlüssele ich das wider ?
Ich habe versucht die zeichen umzudrehen, um quasi die Position wider +97 zu rechnen.
Aber das hat alles nicht funkioniert.

Kann mir jemand helfen ?


Maweki - Sa 11.10.08 19:35

Wenn ich das richtig sehe, ist in der Ursprungsunit sowohl eine ver- als auch eine entschlüsselung dabei.

Das eine basiert auf der "historischen" Methode mit einer virtuellen Buchstabentabelle.

Unter umständen sind beide Funktionen nicht kompatibel (Leerzeichen, Zeilenumbrüche, Sonderzeichen).

Und ich hab mir jetzt das ganze nicht durchgelesen und ich hab auch das letzte mal vor 2 Jahren Lazarus in der Hand gehabt und seitdem nicht mehr, aber das sollte es schon tun:

Delphi-Quelltext
1:
verschiebung := 97 - ord ( key[pos] );                    

Aber das ist nur geraten.

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


Nowo - Sa 11.10.08 21:10

Man bekommt nur Ähnliche werte heraus...
Leider nicht die richtigen.
(dankeschön trotzdem)

Kann jemand helfen ?
Wie dreht man diese function um ?


TomasB - So 12.10.08 07:07

Die intendierte Entschlüsselungsfunktion lautet offensichtlich

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
function entschluessle(inhalt, key: string): string;
var neu: char;
 zaehler, pos, verschiebung : integer;
begin
 inhalt := lowercase ( inhalt );
 key := lowercase ( key );
 result:= '';


 for zaehler := 1 to length ( inhalt ) do
  begin
   pos := zaehler mod length ( key );
    // suche die position im key raus, mit der aktuell verschlüsselt
    // werden soll
   if ( pos = 0 ) then pos := length ( key );
    // mod liefert 0 zurück, wenn die letzte position des keys erreicht ist
   verschiebung := ord ( key[pos] ) - 97;
    // verschiebung berechnen
    //   --> -97 ist nötig, da 97 das kleine a ist
   neu := chr ( ord ( inhalt[zaehler] ) - verschiebung );
    // erst den ascii-wert des aktuellen buchstaben rausfinden,
    // dann verschieben und aus ascii den buchstaben bilden
   if ( ord ( neu ) < 97 ) then
    neu := chr ( ord ( neu ) + 26 );  
    // wenn der ascii-wert unter 97 liegt, müssen 26 stellen addiert
    // werden, damit das ergebnis im bereich der kleinen buchstaben liegt
   result := result + neu;  
  end;
end;

Das funktioniert aber nur, wenn der zu verschlüsselnde Text und der zu entschlüsselnde Text aussschließlich aus Buchstaben bestehen. Sobald ein Leerzeichen oder ein Zeilenendezeichen auftauchen, gibt es Probleme. Die Verschlüsselungsfunktion verschiebt auch ASCII-Zeichen unterhalb von 97. Aus dem Leerzeichen (ASCII = 32) wird so zB. ein Zeichen zwischen leerzeichen (bei Schlüssel 'a') und 9 (ASCII 57 bei Schlüssel 'z'). Beim entschlüsseln wird diese Verschiebung dann rückgängig gemacht, aber bei der Abfrage if ( ord ( neu ) < 97 ) thenwerden diese Zeichen dann fälschlicherweise nochmal verschoben. Das Ergebnis ist natürlich falsch. Davon sind alle Zeichen mit ASCII-Werten unterhalb 97 betroffen (u.a. Leerzeichen, Ziffern, Zeilenendezeichen). Außerdem können bei der Verschlüsselung auch Großbuchstaben (A - Z) entstehen, wenn das zu verschlüsselnde Zeichen einen ASCII-Wert zwischen 40 (='(') und 64 (='@') hat. Beim lowercasein der Entschlüsselung wird daraus ein Kleinbuchstabe, der wieder in einen anderen Kleinbuchstaben statt in das richtige Zeichen entschlüsselt wird. Die Zeichen, deren ASCII-Wert größer als 122 ('z') sind, werden auch falsch behandelt.

Das ließe sich noch beheben, aber das wirkliche Problem ist, das beispielweise aus dem Zeichen ']' (ASCII 93) und dem Schlüssel 'k' beim verschlüsseln das Zeichen 'g' wird, und aus dem beim Entschlüsseln dann das Zeichen 'w'. Mit anderen Worten, für ASCII-Werte zwischen 91 und 96 ist die Verschlüsselung mehrdeutig.

Der wahre Fehler liegt darin, daß die Verschlüsselungsfunktion zwar nur für Kleinbuchstaben sinnvolle Ergebnisse liefert, aber trotzdem auch andere Zeichen anfasst. Sie sollte diese entweder in Ruhe lassen, oder eine Fehlermeldung liefern, beispielsweise so:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
function verschluessle(inhalt, key: string): string;
var neu: char;
 zaehler, pos, verschiebung : integer;
begin
 inhalt := lowercase ( inhalt );
 key := lowercase ( key );
 result:= '';
 for zaehler := 1 to length ( inhalt ) do
  begin
if (inhalt[zaehler]  >='a'and  (inhalt[zaehler] <='z'then
(*wir spielen nur mit den Kleinbuchstaben*)
 begin 
   pos := zaehler mod length ( key );
    // suche die position im key raus, mit der aktuell verschlüsselt
    // werden soll
   if ( pos = 0 ) then pos := length ( key );
    // mod liefert 0 zurück, wenn die letzte position des keys erreicht ist
   verschiebung := ord ( key[pos] ) - 97;
    // verschiebung berechnen
    //   --> -97 ist nötig, da 97 das kleine a ist
   neu := chr ( ord ( inhalt[zaehler] ) + verschiebung );
    // erst den ascii-wert des aktuellen buchstaben rausfinden,
    // dann verschieben und aus ascii den buchstaben bilden
   if ( ord ( neu ) > 122 ) then
    neu := chr ( ord ( neu ) - 26 );  
    // wenn der ascii-wert über 122 liegt, müssen 26 stellen abgezogen
    // werden, damit das ergebnis im bereich der kleinen buchstaben liegt  
 result := result + neu;
end
else begin
  result := result + inhalt[zaehler]  ;

(*tue nichts (oder gib alternativFehlermeldung aus )*)
end;
  
  end;
end;


Dasselbe dann natürlich in der Entschlüsselungsfunktion.

Gruß
Tom

Moderiert von user profile iconNarses: überflüssige Leerzeilen/Umbrüche entfernt