¿Qué tan fácil es descifrar este algoritmo de cifrado? [cerrado]

2

Cuando tenía unos 13 o 14 años, estaba un poco interesado en la criptografía (que es, después de todo, un campo interesante). Aprendí mucho desde entonces (han pasado unos 8 años), pero todavía estoy muy lejos de considerarme un experto en criptografía.

Lo que sea, cuando estaba en esa edad, escribí este pequeño script en perl que acabo de encontrar en un HD antiguo. (Guardado como MyEncrypt.pm)

package MyEncrypt;

use strict;
use warnings;

my @_ALPHABET = ('a' .. 'z', 'A' .. 'Z', 0 .. 10, ' ');
my $_i = 0;
my %_ALPHABET = map { $_i++; $_ => $_i } @_ALPHABET;
$_i = 0;
my %_ALPHABET_REVERSE = map { $_i++; $_i => $_ } @_ALPHABET;

sub new {
    bless +{}, shift
}

sub set_password {
    my $self = shift;
    my $password = shift;
    $self->{hashed_password} = _hash_password($password);
    return $self;
}

sub encrypt {
    my $self = shift;
    my $input = shift;

    my $hashed_password = $self->{hashed_password};
    die "No password set.\n" unless $hashed_password;

    my @split = split(//, $input);

    my $output = shift;
    for (0 .. $#split) {
        my $new_number .= ($_ALPHABET{$split[$_]} + ($hashed_password ** ($_ + 1))) % $#_ALPHABET;
        $output .= $_ALPHABET_REVERSE{$new_number};
    }
    return $output;
}

sub _hash_password {
    my $password = shift;
    my $hash = 1;
    my $i = 1;
    for (split(//, $password)) {
        my $power = length($password) / (2 ** $i);
        $power = 1 if $power < 1;
        $hash *= int($_ALPHABET{$_} ** $power);
        $i++;
    }

    if(is_multiple_of_two($hash)) {
        $hash += 1;
    }

    while (length($hash) != 10) {
        no warnings;
        $hash *= $hash | join('', map { $_ALPHABET{$_} } split(//, $password));
        $hash =~ s/\.//g;
        $hash = substr($hash, 0, 10);
    }
    return $hash;
}

sub is_multiple_of_two {
    my $n = shift;
    my $log = log($n) / log(2);
    if($log == int($log)) {
        return 1;
    } else {
        return 0;
    }
}

1;

(Probablemente tiene el peor algoritmo de hashing. Lo sé).

Este es mi "programa de prueba" para ello:

use strict;
use warnings;
use MyEncrypt;

my $enc = MyEncrypt->new();
$enc->set_password('abc');
die $enc->encrypt("hello world");

Mi idea fue esta: Le damos una contraseña y de alguna manera genera un "hash" de la misma (aquí de una manera que, lo admito, no entiendo bien. Pero hey: han pasado 8 años desde eso ... Por alguna razón , debe tener 10 dígitos y estos se generan hasta que la contraseña tenga 10 dígitos, multiplicando la contraseña con los caracteres OR'd del alfabeto (donde a = 1, ... A = 27, ...) y luego cortarlo a 10 caracteres o menos, hasta que esto lleve a un "hash"), que luego se usará para esta sustitución letra por letra:

x = ( número de la letra actual + password_hash a la potencia de (posición de este carácter + 1) ) módulo el tamaño del alfabeto

y luego x se usa para buscar la letra numerada x , que se agregará a la cadena de salida. Cuando se analiza todo el texto, la salida tendrá una forma completamente diferente de lo que tenía como entrada. Y cuando una letra cambia en la contraseña, toda la cadena es diferente.

Por ejemplo:

string: "hello world", pass: "abc" => 9bkpXY1H0oR
string: "hello world", pass: "abcd" => HS4gVkuWX4U
string: "hello world", pass: "abcda" => DhAqIeHn9cr

y así sucesivamente.

Por supuesto, el código es terrible, el algoritmo de hash es probablemente el peor de todos y la idea no es realmente nueva, pero lo inventé yo mismo y en ese momento estaba muy orgulloso de mí mismo por esto. ¿Pero qué tan seguro hubiera sido esto? ¿Cuánto tiempo necesitaría uno para descifrar esto y cómo se haría? Como he dicho, me desarrollé en muchos campos, pero por alguna razón después de ese guión ya no me importaba mucho la criptografía y mi conocimiento es bastante limitado.

(También, lamentablemente: esta es una versión incompleta de ese archivo. No estoy 100% seguro, pero creo que tuve algún tipo de rutina de descifrado (sin embargo, esto podría ser falso. Podría haber estado en otro intento), que parece perdido. Por lo tanto, ni siquiera puedo decir si esta versión del algoritmo se podría descifrar de una manera fácil si tiene la contraseña. Ni siquiera noté esto al ver este archivo por primera vez).

Gracias.

    
pregunta kono 24.07.2014 - 23:13
fuente

1 respuesta

1

Esto sería trivial de atacar si el código realmente hiciera lo que pretendías y fuera descifrable. (Aunque no lo hace). Tienes que probar los 63 valores diferentes (la longitud de tu alfabeto) de hashes, el tamaño del alfabeto y luego puedes descifrar cualquier mensaje.

Esencialmente cambias cada carácter por H p + 1 módulo 63, donde H es el valor de hash calculado. Ahora debes tener en cuenta matemáticamente que H p mod N es el mismo que (H mod N) p mod N. Así que, independientemente de la forma elegante de construir el hash, existen Sólo efectivamente 63 hashes diferentes. Simplemente necesitas probarlos todos.

Concedido, esto supone que su código realmente funciona y es descifrable, lo que no es posible en este momento.

Por ejemplo, para pw="abc" el hash es 8486571168. Nota perl no hace cálculos de precisión arbitraria. Entonces, 8486571168**2 en perl es 7.20218901895289e+19 como es 8486571168**2 + $x para cualquier valor de $ x de 0 a 63.

Puede demostrar esto fácilmente usando la misma contraseña ( 'abc' ) para cifrar, por ejemplo, "hBROKEN1234" o "hNOTWORKING" (o cualquier otra cosa que comience con h ) que también irá a "9bkpXY1H0oR" . Puede solucionar este problema utilizando la función exponentiation modular , en cuyo punto el ataque descrito anteriormente podría descifrarlo al probar 63 valores diferentes del hash.

    
respondido por el dr jimbob 25.07.2014 - 00:15
fuente

Lea otras preguntas en las etiquetas