Du kannst in jedem Kryptographiebuch nachlesen dass vor selbst entworfenen Algorithmen massivst gewarnt wird! Nicht umsonst wurden standardisierte Algorithmen über Jahrzehnte hinweg auf Schwachstellen überprüft. Der Einsatz von symmetrischen Verschlüsselungen sollte immer mit einem Standardalgorithmus durchgeführt werden! Vor allem wenn man sich in der Kryptographie nicht auskennt.
Ryu's Coder Cracker
Dein Algorithmus ist z.B. gegen Known-Plaintext Angriffe sehr schwach. Grad bei Zugangsdaten wie du meinst ist es oftmals leicht an so einen Plaintext zu kommen (DB Host ist zum Beispiel meist localhost). Da bei deiner Verschlüsselung auch die Länge des Plaintextes bekannt ist kann man somit auch recht einfach sehen dass es sich um localhost handelt (beide l's erkennt man und beide o's zum Beispiel. Kennt man jetzt noch das Alphabet (das du schon vorgibst) kann man sehr einfach den Key berechnen.
Ich hab eine Funktion geschrieben mit der man recht einfach das zurückrechnen kann. Es ist sogar nicht mal nötig den kompletten Plaintext zu kennen. Es reicht wenn man einen einzigen Buchstaben kennt der überein stimmt.
Beispiel: Ich habe localhost mit dem Passwort 24687 verschlüsselt. Ciphertext ist 56448:64512:32256:26880:56448:45696:64512:75264:77 952.
Angenommen ich weiß jetzt dass das dritte Zeichen ein "c" ist dann gibt meine Funktion folgendes aus:
PHP-Code:
$plaintext = "xxcxxxxxx"; // nur c ist uns bekannt
$cipher = "56448:64512:32256:26880:56448:45696:64512:75264:77952";
// alphabet wie oben
$keys = getKeys($plaintext, $cipher, $alphabet);
var_dump($keys);
Ausgabe:
Code:
array
0 =>
array
'char' => string 'x' (length=1)
'key' => string '2335' (length=4)
'decoded' => string '' (length=0)
1 =>
array
'char' => string 'x' (length=1)
'key' => string '2' (length=1)
'decoded' => string '' (length=0)
2 =>
array
'char' => string 'c' (length=1)
'key' => string '222222237' (length=9)
'decoded' => string 'localhost' (length=9)
3 =>
array
'char' => string 'x' (length=1)
'key' => string '21' (length=2)
'decoded' => string '' (length=0)
4 =>
array
'char' => string 'x' (length=1)
'key' => string '2335' (length=4)
'decoded' => string '' (length=0)
5 =>
array
'char' => string 'x' (length=1)
'key' => string '222' (length=3)
'decoded' => string '' (length=0)
6 =>
array
'char' => string 'x' (length=1)
'key' => string '2' (length=1)
'decoded' => string '' (length=0)
7 =>
array
'char' => string 'x' (length=1)
'key' => string '22235' (length=5)
'decoded' => string '' (length=0)
8 =>
array
'char' => string 'x' (length=1)
'key' => string '2' (length=1)
'decoded' => string '' (length=0)
Wie du siehst konnte ich bei Zeichen "c" einen entsprechenden Schlüssel berechnen der den kompletten Ciphertext entschlüsseln kann. Der Schlüssel wäre hier: 222222237. Dabei sieht man dein Problem. Du verwendest eine einfache Multiplikation. Daher ist ein Schlüssel 234 das selbe wie 243 oder sogar 2322 oder 2223. Also auch der Originalschlüssel 24687 = 2 22 23 2222 7 (wie oben).
Würde ich den kompletten Plaintext kennen (nicht nur ein Zeichen) würde an allen Stellen der Key berechnet werden, es ist also nur eine einzige Übereinstimmung zwischen Plaintext und meinem "geratenen" Plaintext nötig um deine Verschlüsselung auszuhebeln. Somit wäre es auch möglich einfach mal alle möglichen Buchstaben durchzuprobieren und dann mit den berechneten Schlüsseln dann einfach auszuprobieren welcher der richtige ist.
Hier noch die Funktion zum cracken:
PHP-Code:
function getKeys($plaintext, $cipher, $alphabet) {
$plainchars = str_split($plaintext);
$cipherchars = explode(":", $cipher);
$result = array();
for ($i = 0; $i < count($plainchars); $i++) {
$s_bst = array_search($plainchars[$i], $alphabet);
$number = $cipherchars[$i] / $s_bst;
$key = getDivider($number);
$result[] = array(
'char' => $plainchars[$i],
'key' => $key,
'decoded' => decode($cipher, $key, $alphabet)
);
}
return $result;
}
function getDivider($number) {
$result = '';
$possibleValues = array(2,3,4,5,6,7,8,9,10,11);
foreach ($possibleValues as $div) {
while(true) {
if ($number%$div == 0) {
if ($div == 10) $result .= 0;
elseif ($div == 11) $result .= 1;
else $result .= $div;
$number /= $div;
} else {
break;
}
}
}
return $result;
}
Deine Verschlüsselung habe ich innerhalb von 30 Minuten geknackt. Und ich habe nur Grundlegende Kenntnisse in Kryptographie. Schon gar nicht davon wie man Algorithmen auf Schwachstellen überprüft oder diese ausnutzt. Von daher solltest du dir wirklich überlegen ob du nicht lieber auf standardisierte Algorithmen ausweichst und nicht deine eigenen implementieren willst.