Quanto è facile decifrare questo algoritmo di crittografia? [chiuso]

2

Quando avevo circa 13 o 14 anni, ero un po 'interessato alla crittografia (che è, dopotutto, un campo interessante). Ho imparato parecchio da allora (sono passati circa 8 anni da allora), ma sono ancora molto lontano dal concedermi un esperto di crittografia.

Qualunque cosa, quando ero a quell'età, ho scritto questo piccolo script perl che ho appena trovato su un vecchio HD. (Salvato come 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;

(Probabilmente ha il peggiore algoritmo di hashing di sempre. Lo so)

Questo è il mio "programma di test" per questo:

use strict;
use warnings;
use MyEncrypt;

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

La mia idea era questa: Diamo una password e in qualche modo genera un "hash" (in un modo che, lo ammetto, non lo capisco più.) Ehi: sono passati 8 anni da quel ... Per qualche ragione , deve essere lungo 10 cifre e vengono generati da, fino a quando la password è lunga 10 cifre, moltiplicando la password con i caratteri OR dell'alfabeto (dove a = 1, ... A = 27, ...) e poi tagliandolo a 10 caratteri o meno, fino a quando questo porta a un "hash"), che viene poi utilizzato per questa sostituzione lettera per lettera:

x = ( numero della lettera attuale + password_hash alla potenza di (posizione di questo personaggio + 1) ) modulo la dimensione dell'alfabeto

e quindi x viene utilizzato per cercare la lettera numerata x , che verrà aggiunta alla stringa di output. Una volta passato tutto il testo, l'output avrà una forma completamente diversa di ciò che ha avuto come input. E quando una lettera cambia nella password, l'intera stringa è diversa.

Ad es .:

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

e così via.

Naturalmente, il codice è terribile, l'algoritmo di hashing è probabilmente il peggiore di sempre e l'idea non è davvero nuova, ma l'ho inventata io stesso e in quel momento ero abbastanza orgoglioso di me stesso per questo. Ma quanto sarebbe stato sicuro? Quanto tempo è necessario decifrare questo e come si farebbe? Come ho detto, mi sono sviluppato in molti campi, ma per qualche ragione dopo quella sceneggiatura non mi importava più della crittografia e le mie conoscenze sono piuttosto limitate.

(Inoltre, purtroppo: questa è una versione incompleta di quel file. Non sono sicuro al 100%, ma credo che abbia avuto qualche problema di decrypt-routine (anche se potrebbe essere falso. Potrebbe essere stato in un altro tentativo), che sembra perduto, quindi non posso nemmeno dire se questa versione dell'algoritmo possa essere decifrata in modo semplice se si ha la password. Non ho nemmeno notato questo a prima vista di nuovo questo file).

Grazie.

    
posta kono 24.07.2014 - 23:13
fonte

1 risposta

1

Questo sarebbe banale da attaccare se il codice effettivamente facesse ciò che intendevi e fosse decifrabile. (Non però). Devi provare tutti i 63 (lunghezza del tuo alfabeto) valori diversi degli hash per formare la dimensione dell'alfabeto e quindi puoi decifrare qualsiasi messaggio.

In sostanza si sposta ciascun carattere di H p + 1 modulo 63, dove H è il valore di hash calcolato. Ora dovresti notare matematicamente che il mod H p è lo stesso di (H mod N) p mod N. Quindi, a prescindere dal modo ingegnoso di costruire l'hash, ci sono solo efficacemente 63 diversi hash. Devi semplicemente provarli tutti.

Ammesso che questo presupponga che il tuo codice funzioni effettivamente e sia decifrabile, cosa che non è al momento.

Ad esempio, per pw="abc" l'hash è 8486571168. Nota perl non fa matematica di precisione arbitraria. Quindi 8486571168**2 in perl è 7.20218901895289e+19 come 8486571168**2 + $x per qualsiasi valore di $ x da 0 a 63.

Puoi facilmente dimostrarlo usando la stessa password ( 'abc' ) per crittografare diciamo "hBROKEN1234" o "hNOTWORKING" (o qualsiasi altra cosa che inizia con h ) sempre di cui anche "9bkpXY1H0oR" . È possibile risolvere questo problema utilizzando una funzione modulo modulare di elevazione , a quel punto il l'attacco descritto sopra potrebbe decodificarlo provando 63 diversi valori dell'hash.

    
risposta data 25.07.2014 - 00:15
fonte

Leggi altre domande sui tag