Cryptor - Ein symmetrisches Verschlüsselungsverfahren

    • C#

    Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von MrTrebron.

      Cryptor - Ein symmetrisches Verschlüsselungsverfahren

      Guten Abend. :)

      Ich möchte euch heute mein Verschlüsselungsverfahren Cryptor vorstellen: Das ganze ist ein symmetrisches Verschlüsselungsverfahren, d.h. es wird das gleiche Passwort zum ver- und entschlüsseln verwendet. Mit diesem Verfahren kann man sowohl Texte als auch Dateien mit Texten oder Dateien verschlüsseln. Das ganze ist relativ einfach: Zuerst wird die binär Datei eingelesen, bzw. der String in ein Byte-Array konvertiert. Danach erfolgt das selbe für das Passwort. Danach geht man jedes Byte im Input durch und addiert zu jedem Byte des Inputs jedes Byte des Passworts. Am Ende erhält man eine relativ lange Zahl, welche dann in der Ausgangsdatei abgespeichert wird. Zum Entschlüsseln subtrahiert man einfach jedes Byte des Passworts von jedem Byte des Inputs, sodass man wieder die Originaldatei erhält.

      Ich weiß nicht, ob es an meiner Implementierung liegt, oder generell am Verfahren, aber in der Ausgangsdatei folgen immer nach zwei Bytes, deren Wert ungleich Null ist, sechs leere. Wenn man diese nun löscht ist die verschlüsselte Datei unabhängig vom Passwort immer genau doppelt so groß wie der Input.

      Meine Implementierung dieses Verfahrens ist nicht sonderlich gut, da sowohl Passwort als auch Dateigröße vom Input beschränkt sind. Wenn man sich mühe gibt und einen gescheiten Algo schreibt, ist dies natürlich nicht der Fall. Weiterhin erfolgt die Verschlüsselung einer Datei in wenigen Millisekunden bis Sekunden, während die Entschlüsselung der selben Datei mehrere Minuten bis Stunden braucht. Aber auch dies kann an meiner Implementierung liegen.

      Implementierung

      C#-Quellcode

      1. using System;
      2. using System.Collections.Generic;
      3. using System.IO;
      4. // inputData enthält die Datei, die ver- oder entschlüsselt werden soll
      5. // passwordData enthält das Passwort
      6. static byte[] inputData, passwordData;
      7. // hier drin wird entweder das passwort als Zeichenfolge
      8. // oder der pfad zu der datei, die als Passwort genutzt
      9. // werden soll gespeichert
      10. static string password, outputPath; // im outputPath wird der Pfad zur Ausgabedatei gespeichert
      11. void LoadPasswordData()
      12. {
      13. // falls das Passwort keine Datei sondern eine Zeichenfolge ist,
      14. // soll diese in ein Byte-Array konvertiert werden
      15. passwordData = new byte[password.Length];
      16. int index = 0;
      17. foreach (char c in password)
      18. {
      19. password[index++] = Convert.ToByte(c);
      20. }
      21. // falls eine Datei als "Passwort" verwendet werden soll, muss
      22. // diese eingelesen werden
      23. passwordData = File.ReadAllBytes(password); // try catchen nicht vergessen ;)
      24. }
      25. void Encrypt()
      26. {
      27. List<ulong> encrypted = new List<ulong>(); // enthält jedes verschlüsselte byte
      28. List<byte> encryptedData = new List<byte>(); // enthält jede ulong aus encrypted
      29. List<byte> outputData = new List<byte>(); // enthält die fertige, verschlüsselte datei
      30. LoadPasswortData();
      31. // nun wird jedes Byte in passwordData zu jedem Byte in inputData addiert
      32. // das ganze wird jeweils in einer ulong gesichert, da dabei eine große Zahl rauskommen kann
      33. ulong currentByte;
      34. foreach (byte b in inputData)
      35. {
      36. currentByte = b;
      37. foreach (byte c in passwordData)
      38. {
      39. currentByte += c;
      40. }
      41. encrypted.Add(currentByte); // das ganze nun noch der List hinzufügen
      42. }
      43. // jetzt wird jede ulong in ihre 8 bytes aufgespalten und jedes ihrer bytes
      44. // der encryptedData hinzugefügt
      45. foreach (ulong ul in ecrypted)
      46. {
      47. for (int i = 0; i < 8; i++)
      48. {
      49. encryptedData.Add(BitConverter.GetBytes(ul)[i]);
      50. }
      51. }
      52. // nun werden die seches leeren Bytes, die immer nach zwei "vollen"
      53. // Bytes auftreten entfernt, bzw. immer die beiden vollen werden
      54. // zur outputData hinzugefügt
      55. for (int i = 0; i < encryptedData.Count; i += 8)
      56. {
      57. outputData.AddRange(new byte[] { encryptedData[i], encryptedData[i + 1] });
      58. }
      59. // nun enthält outputData die fertige verschlüsselte Datei und kann
      60. // so gespeichert werden
      61. File.WriteAllBytes(outputPath, outputData.ToArray()); // try catch nicht vergessen ;)
      62. }
      63. void Decrypt()
      64. {
      65. List<byte> inputFilled = new List<byte>(); // enthält die inputData mit den eingefügten, fehlenden bytes
      66. // enhält die fertige, entschlüsselte datei oder zeichenfolge zum speichern
      67. // falls es ursprünglich eine zeichenfolge war, einfach als *.txt (Raw Text) speichern
      68. List<byte> outputData = new List<byte>();
      69. LoadPasswordData();
      70. // nun fügen wir der inputData die fehlenden, leeren bytes wieder hinzu
      71. inputFilled.AddRange(inputData);
      72. int index = 2;
      73. do
      74. {
      75. // falls der index größer ist, als der count der liste
      76. // noch die letzten sechs hinzufügen und danach die schleife verlassen
      77. if (index >= inputFilled.Count -1)
      78. {
      79. inputFilled.AddRange(new byte[] { 0, 0, 0, 0, 0, 0 });
      80. break;
      81. }
      82. inputFilled.InsertRange(index, new byte[] { 0, 0, 0, 0, 0, 0 });
      83. index += 8;
      84. } while (inputFilled[inputFilled.Count - 1] != 0);
      85. // nun muss die datei wieder entschlüsselt werden, d.h. von jedem
      86. // byte im input jedes byte des passwortes wieder abziehen
      87. ulong currentByte;
      88. for (int i = 0; i < inputFilled.Count; i += 8)
      89. {
      90. currentByte = BitConverter.ToUInt64(inputFilled.ToArray(), i);
      91. // diese for-schleife muss eigentlich nicht rückwärts laufen,
      92. // ist aber noch ein überbleibsel aus einer alten version
      93. for (int it = passwordData.Length - 1; it > - 1; it--)
      94. {
      95. currentByte -= passwordData[it];
      96. }
      97. // zum schluss das byte noch der fertigen datei hinzufügen
      98. // mir ist klar, dass das ganze abstürzt, wenn man bspw.
      99. // ein falsches passwort verwendet, ist mir aber egal :D
      100. outputData.Add(Convert.ToByte(currentByte));
      101. }
      102. // zum schluss noch die fertige datei speichern
      103. File.WriteAllBytes(outputPath, outputData.ToArray());
      104. }



      Im Anhang ist eine nicht ganz so saubere -dafür aber ausführbare- Implementierung des Verfahrens, die auch nur die Verwendung einer Zeichenfolge als Passwort erlaubt. Es ist besser, wenn Ihr euch eine eigene Version mit dem obigen Quellcode kompiliert.

      Verwendung: Dieses Projekt ist nur zum Spaß irgendwann morgends in der Früh entstanden, aus langeweile. Trotzdem bin ich vorerst nicht damit einverstanden, dass ihr den Quellcode in irgendeiner Art und Weiße verwendet (außer zum testen) oder veröffentlicht (auch nicht in abgewandelter Version!). Ich möchte erstmal euer Feedback zum Verfahren an sich hören, eventuell ist das ganze ja nicht mal sicher.


      Bin gespannt auf euer Feedback ^^

      LG :)

      ~ides
      Dateien
      • Cryptor.zip

        (3,84 kB, 96 mal heruntergeladen, zuletzt: )
      Ich weiß nicht, ob es an meiner Implementierung liegt, oder generell am Verfahren, aber in der Ausgangsdatei folgen immer nach zwei Bytes, deren Wert ungleich Null ist, sechs leere.

      Das hängt von der Länge deines Passworts ab. Bei 257 * 0xFF sollten z.B. auch mal mehr als zwei Byte herauskommen.

      Zum Algo:
      currentByte = b; foreach (byte c in passwordData) { currentByte += c; } ist äquivalent zu currentByte = b + x mit einem x, welches nur vom Passwort abhängt (und nicht von den Daten).
      Wenn du noch eine mod-Operation ergänzt hast du damit praktisch die klassische Caesar-Verschlüsselung. Mit allen Schwächen.
      (Der Algo ist also nicht so toll.)
      Zudem gibt es bei deinem Algo immer mehrere Passwörter zum Entschlüsseln ("ab" führt z.B. zum gleichen Ergebnis wie "ba").

      Trotzdem bin ich vorerst nicht damit einverstanden, dass ihr den Quellcode in irgendeiner Art und Weiße verwendet[...]

      Ähm...

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „3daycliff“ () aus folgendem Grund: Typo...

      3daycliff schrieb:

      Trotzdem bin ich vorerst nicht damit einverstanden, dass ihr den Quellcode in irgendeiner Art und Weiße verwendet[...]

      Ähm...

      Damit ist gemeint, falls es tatsächlich was brauchbares wäre, dass dann nicht irgendjemand hingeht und das klaut. ;)

      Ja, war mir irgendwie von Anfang an klar, dass das ganze vermutlich nur Schrott ist, aber ich wollte halt trotzdem mal ein Feedback dazu hören, da ich selbst noch relativ neu in der Kryptografie bin, mich damit aber gerne beschäftige.

      LG :)

      3daycliff schrieb:


      ichduersie schrieb:

      Trotzdem bin ich vorerst nicht damit einverstanden, dass ihr den Quellcode in irgendeiner Art und Weiße verwendet[...]

      Ähm...


      Damit ist gemeint, falls es tatsächlich was brauchbares wäre, dass dann nicht irgendjemand hingeht und das klaut.


      Dann ist das der falsche Bereich, du bist hier im Sourcecode-Austausch, jeder darf es benutzen. Sonst habe ich nichts neues mehr hinzuzufügen.

      ichduersie schrieb:

      ich selbst noch relativ neu in der Kryptografie bin, mich damit aber gerne beschäftige.

      Wenn man sich auch nur ein klitzekleines bisschen mit Kryptografie beschäftigt hat, sollte man doch sehen, dass diese "Verschlüsselung" nicht zu gebrauchen ist? Ich liste mal ein paar Dinge auf:
      • Viel zu viele Kollissionen (wie 3daycliff mit ab und ba schon sagte)
      • Praktisch nur Anwendung der Caesar-Verschlüssung (wie 3daycliff ebenfalls schon gesagt hatte)
        • Angriffsmöglichkeit, welche sich daraus ergibt: Höchsten und niedrigsten Long-Wert raussuchen (können ja max. 256 auseinander sein); mit ein bisschen Glück ergibt sich eine ziemlich hohe Differenz -> nur ein paar durchprobieren, dann hat man den Wert raus
        • Weitere Angriffsmöglichkeit: Hat man nur ein Bruchstück der ursprünglichen Datei, kann man den Teil in der verschlüsselten Datei suchen, bei welchem die Differenzen zwischen den Longs den Differenzen zwischen den Bytes in der ursprünglichen Datei entsprechen, dann das Ganze subtrahieren -> Rotation rausgefunden
      • Du kriegst auch mit nem ULong ständig Overflows, sobald du ein längeres Passwort hast
      • Was bitte soll folgender Code tun?

        C#-Quellcode

        1. // nun werden die seches leeren Bytes, die immer nach zwei "vollen"
        2. // Bytes auftreten entfernt, bzw. immer die beiden vollen werden
        3. // zur outputData hinzugefügt
        4. for (int i = 0; i < encryptedData.Count; i += 8)
        5. {
        6. outputData.AddRange(new byte[] { encryptedData[i], encryptedData[i + 1] });
        7. }

      Ich hatte das ganze bisher nur mit Passwörtern probiert, welche kürzer als 256 Zeichen waren, sodass nach zwei Bytes immer sechs leere kamen, welche die Dateigröße in die höhe getrieben haben, also lösche ich die einfach raus. Gut, dann müsste man halt leider das Passwort begrenzen, oder das ganze dynamisch, evtl. mit BigIntegern gestalten, sodass 1. nichts mehr überläuft und 2. keine leeren Bytes mehr drin sind.

      Im Anhang ist ein Screenshot einer verschlüsselten Datei, die ich mit einer Version verschlüsselt habe, wo dieser Quellcodeteil auskommentiert ist. Mir ist auch klar, woher das kommt, aber ehrlich gesagt, ich hatte keine Lust das besser zu gestalten.
      Bilder
      • scr.jpg

        364,69 kB, 1.395×630, 224 mal angesehen
      Es ist grundsätzlich keine Gute Idee eigen Verschlüsselungsverfahren zu entwickeln.

      Eine einfache Google Suche liefert dir genug Gründe warum man es nicht machen sollte:
      z.B.: security.stackexchange.com/que…-shouldnt-we-roll-our-own

      Und selbst wenn es nur "experimentell" sein soll, dann zuerst mal die Theorie dazu lernen und, ganz wichtig, verstehen. Danach kann man nochmal darüber nachdenken.

      Ist nicht böse gemeint, aber es gibt bereits genug schlechte Verschlüsselungen die in Software eingesetzt wird.
      SWYgeW91IGNhbiByZWFkIHRoaXMsIHlvdSdyZSBhIGdlZWsgOkQ=

      Weil einfach, einfach zu einfach ist! :D
      Erstens: Dein Code ist prädestiniert für Sinlose Speicher verschwendung (nicht böse gemeint). Desweiteren wie erwähnt komisch Programmiert mit den ULong, und der Algo ist nicht neu, höchstens als anfänger experiment zu gebraucht und wen man es so wertet dann ganz gut. Ansonsten idelal für 5 Jährige Script Kiddys die ihr Tagebuch vor den eltern verstecken wollen.

      Ich würde es begrüßen wen es SSL-Implementierungen geben würde wo der Crypto Stream, usw... erleutert wird.

      LG, J.Herbrich

      J.Herbrich schrieb:

      Ansonsten idelal für 5 Jährige Script Kiddys die ihr Tagebuch vor den eltern verstecken wollen.

      So eine Aussage finde ich schon etwas unschön, da sie nur dazu dient den Beitrag bzw. dessen Inhalt als negativ und schlecht darzustellen.
      Wenn es Vorschläge und Kritik gibt, kann diese in Form von konstruktiven Beiträgen geäußert werden, was ja auch von Deiner Seite aus teils geliefert wurde, allerdings ist so ein Nebensatz unnötig und ich möchte mich dafür aussprechen, sowas zu unterlassen.

      Grüße
      #define for for(int z=0;z<2;++z)for // Have fun!
      Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

      Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
      Endschuldigung wen es fallsch rüber kommt, aber ich habe mit 9 sowas gemacht als ich angefangen habe mit den Programmieren von vb.net, also von darher bezog sich die Ausage mehr oder weniger matematisch umkorrekt auf meine eigenen erfahrungen.

      LG, J.Herbrich

      J.Herbrich schrieb:

      Ansonsten idelal für 5 Jährige Script Kiddys die ihr Tagebuch vor den eltern verstecken wollen.


      Halte ich schon für sehr angreifend und deine Erläuterung in Post 11 hilft da nicht viel.

      Man sollte sich auch immer erst mal an die eigene Nase fassen.

      @TE: Ich denke auch das es vielleicht eine nette Fingerübung gewesen sein mag, aber ich denke man sollte Grundlegend erst einmal die Kryptographie halbwegs beherrschen bevor man so etwas angeht.
      Die deutsche Sprache ist Freeware, du kannst sie benutzen, ohne dafür zu bezahlen. Sie ist aber nicht Open Source, also darfst du sie nicht verändern, wie es dir gerade passt.