scoprire la chiave di cifratura

Postate qui per tutte le discussioni legate alla sicurezza di Linux/Slackware

Moderatore: Staff

Regole del forum
1) Citare sempre la versione di Slackware usata, la versione del Kernel e magari anche la versione della libreria coinvolta. Questi dati aiutano le persone che possono rispondere.
2) Specificare se discussione/suggerimento o richiesta d'aiuto.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
ocman
Linux 2.x
Linux 2.x
Messaggi: 239
Iscritto il: gio 31 lug 2008, 18:18
Slackware: ArchLinux
Desktop: xfce
Distribuzione: OpenIndiana

Re: scoprire la chiave di cifratura

Messaggio da ocman »

ora non riesco a guardarci ma ti dico subito che IV è appunto l'Initialization Vector

come dice sotto serve solo per inizializzare gi algorimi di cifratura basati su DES come CBC e CFB che necessitano alla prima 'passata' in input una stringa arbitraria nota ma che non dipenda dal testo in chiaro.

"The first block will need an initial value, and this value is called the initialization vector (IV). Since the IV simply alters the data before any encryption, the IV should be random but does not necessarily need to be kept secret. There are a variety of modes, such as CBC (Cipher Block Chaining), CFB (Cipher Feedback Mode), and OFB (Output Feedback Mode). ECB (Electronic Cookbook Mode) is a mode with no feedback."

Avatar utente
ZeroUno
Staff
Staff
Messaggi: 5441
Iscritto il: ven 2 giu 2006, 14:52
Nome Cognome: Matteo Rossini
Slackware: current
Kernel: slack-current
Desktop: ktown-latest
Distribuzione: 01000000-current
Località: Roma / Castelli
Contatta:

Re: scoprire la chiave di cifratura

Messaggio da ZeroUno »

e la sigla di iv l'avevo capita.

Intanto ho scoperto anche che né l'IV né il SALT li devo considerare in base64 ma in hex, e che openssl enc li accetta come parametri, ma in nessun modo sono riuscito a specificare il numero di iterazioni (esiste solo sul pkcs8 e consente solo forzare a 1 con un parametro), né il protocollo che usa java, e quindi ottenere l'output del programma java:

Codice: Seleziona tutto

echo -n 'pippo' | openssl enc -a -e -iv 68CF836E78C0A6B1 -S 0102030405060708  -des-cbc -p -pass pass:una_stringa
salt=0102030405060708
key=081DE8E8F25CD05B
iv =68CF836E78C0A6B1
U2FsdGVkX18BAgMEBQYHCBbB/qN8OdGJ
google non mi dice un granchè
(ho provato anche con altri oltre a des-cbc)
a quanto pare poi la tripletta PBEWithMD5AndDES vale anche questa solo per pkcs8
Packages finder: slakfinder.org | Slackpkg+, per aggiungere repository a slackpkg

Codice: Seleziona tutto

1011010 1100101 1110010 1101111 - 0100000 - 1010101 1101110 1101111

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6629
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: scoprire la chiave di cifratura

Messaggio da targzeta »

Vi dico quello che ho capito io. In pratica l'algoritmo usato dal programma di 01 è un DES in CBC che usa come padding PKCS5Padding. Io ho fatto un programma in C con l'ausilio delle openssl che dovrebbe trovare la chiave di un DES però fatto con ECB e non con CBC.

Il CBC vuole anche un ivec (IV nel post di ocman) che non dipende né dal testo né dalla chiave. Avere l'ivec quindi è abbastanza necessario. Vi rimando a questo link per capire meglio. Secondo me si dovrebbe usare in chiaro un testo da 8byte senza caratteri particolari (per evitare il calcolo dell'UTF8), com'è appunto la stringa "Emanuele", eliminando il problema del padding e rendendo il calcolo molto veloce. Nello schema mostrato nel link in pratica si rimarrebbe solo al primo blocco conoscendo "Plaintext", "Initialization Vector (IV)" e "Chiphertext", con l'unica incognita della "key". Penso ci voglia un bruteforce per trovare la chiave, anche perché, mi sono ricordato, che la teoria vuole proprio che un algoritmo sia tanto più forte quando più è difficile trovare la chiave sapendo tutto il resto.

Per openssl:
---------------
Dal codice che ha postato 01 si trova quanto segue:

Codice: Seleziona tutto

SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
da cui, cercando su internet si arriva qui, dove si legge:

Codice: Seleziona tutto

PBEWithMD5AndDES: The password-based encryption algorithm as defined in: RSA Laboratories, "PKCS #5: Password-Based Encryption Standard," version 1.5, Nov 1993. Note that this algorithm implies CBC as the cipher mode and PKCS5Padding as the padding scheme and cannot be used with any other cipher modes or padding schemes.
e questa versione è implementata nelle openssl dal comando pkcs8 a cui va passato il paramentro '-v1 PBE-MD5-DES'.

Prossima tappa:
--------------------
Se non si riesce a trovare la chiave dai sorgenti, secondo me si potrebbe provare un bruteforce, però dovremmo implementare un programma che cifri il testo nello stesso modo che fa il programma Java di 01. Io nel mio programmino ho implementato già una funzioncina stupida che itera tutte le 2^56 chiavi possibili. Ovviamente ci vuole un bel po' per testare tutte le chiavi, però se si hanno più PC a disposizione si può far si che ogni PC testi un sottoinsieme di chiavi in modo da velocizzare il calcolo.
Alternativamente al C si può usare un semplice programma Java con gli stessi parametri, penso che il java sia lento nella prima esecuzione, però poi a VM avviata tutto dovrebbe essere molto più rapido. Con il Java però dovrei implementarmi la funzione che itera le chiavi.

Emanuele

P.S. Notate infine che il testo cifrato è codificato in base64 :)
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

ocman
Linux 2.x
Linux 2.x
Messaggi: 239
Iscritto il: gio 31 lug 2008, 18:18
Slackware: ArchLinux
Desktop: xfce
Distribuzione: OpenIndiana

Re: scoprire la chiave di cifratura

Messaggio da ocman »

il secondo post non esiste più?

Avatar utente
ZeroUno
Staff
Staff
Messaggi: 5441
Iscritto il: ven 2 giu 2006, 14:52
Nome Cognome: Matteo Rossini
Slackware: current
Kernel: slack-current
Desktop: ktown-latest
Distribuzione: 01000000-current
Località: Roma / Castelli
Contatta:

Re: scoprire la chiave di cifratura

Messaggio da ZeroUno »

Quindi ammesso di conoscere solamente
1) testo arbitrario in chiaro
2) relativo testo cifrato
3) algoritmo usato (PBE-MD5-DES)

non sarebbe possibile risalire alla chiave perchè prima della chiave bisogna ricavare l'IV

Invece avendo l'intero programma, (e quindi IV, chiave, numero iterazioni e quant'altro), è possibile capire quali dovrebbero essere i parametri di openssl per fare la criptazione/decriptazione?

ocman ha scritto:il secondo post non esiste più?
quale post?
Packages finder: slakfinder.org | Slackpkg+, per aggiungere repository a slackpkg

Codice: Seleziona tutto

1011010 1100101 1110010 1101111 - 0100000 - 1010101 1101110 1101111

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6629
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: scoprire la chiave di cifratura

Messaggio da targzeta »

ocman ha scritto:il secondo post non esiste più?
Si, esiste ancora, però non è che ci possa capire più di tanto. Diciamo che mi sono sbagliato e che un bruteforce non serve però, penso che un bruteforce sul DES ECB non sia poi così improponibile. E' vero che 2^56 dovrebbero essere circa 6 milioni di miliardi di chiavi però, con i computer moderni a 2GHz e passa, ovvero a 4 miliardi di operazioni al secondo, penso ce la si possa fare in un tempo ragionevole.
Il problema del CBC è che per ogni chiave esistono anche 2^64 valori di IV che ne modificano il comportamento. Quindi con il bruteforce, se non hai l'IV sei messo male.

Poi, può anche essere che non sto capendo niente :),
Emanuele
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6629
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: scoprire la chiave di cifratura

Messaggio da targzeta »

ZeroUno ha scritto:...
Invece avendo l'intero programma, (e quindi IV, chiave, numero iterazioni e quant'altro), è possibile capire quali dovrebbero essere i parametri di openssl per fare la criptazione/decriptazione?
Se ci passi il codice sorgente possiamo vedere di fare qualcosa insieme.

Emanuele
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

ocman
Linux 2.x
Linux 2.x
Messaggi: 239
Iscritto il: gio 31 lug 2008, 18:18
Slackware: ArchLinux
Desktop: xfce
Distribuzione: OpenIndiana

Re: scoprire la chiave di cifratura

Messaggio da ocman »

spina ha scritto:
ocman ha scritto:il secondo post non esiste più?
E' vero che 2^56 dovrebbero essere circa 6 milioni di miliardi di chiavi però, con i computer moderni a 2GHz e passa, ovvero a 4 miliardi di operazioni al secondo, penso ce la si possa fare in un tempo ragionevole.
sono daccordo. anzi sarà sicuramente molto veloce.
comunque non intendevo quello ma forse che in quel documento c'è un algoritmo in pseudocodice già bello e pronto. spesso lo fanno in quei tipo di paper e quindi vi evita molti sbattimenti. stasera lo scarico poi al massimo copio incollo la parte che serve.

UPDATE: no nessun pseudocodice solo dimostrazioni algebriche dell'attacco
Ultima modifica di ocman il lun 7 mar 2011, 17:47, modificato 1 volta in totale.

Avatar utente
ZeroUno
Staff
Staff
Messaggi: 5441
Iscritto il: ven 2 giu 2006, 14:52
Nome Cognome: Matteo Rossini
Slackware: current
Kernel: slack-current
Desktop: ktown-latest
Distribuzione: 01000000-current
Località: Roma / Castelli
Contatta:

Re: scoprire la chiave di cifratura

Messaggio da ZeroUno »

E' quello che ho già inviato (per la sola parte di criptazione). Dall'originale cambiano solamente le variabili salt,temp,iterationCount
comunque lo riposto intero, ma il resto non aggiunge nulla di significativo al precedente.

Codice: Seleziona tutto

import java.io.PrintStream;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;


class Encrypt
{
  Cipher ecipher;
  Cipher dcipher;
  byte[] salt = { 1, 2, 3, 4, 5, 6, 7, 8 };
  int iterationCount = 10;
  public Encrypt() {
    try {
      String temp = "una_stringa";
      KeySpec keySpec = new PBEKeySpec(temp.toCharArray(), this.salt, this.iterationCount);
      SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
      this.ecipher = Cipher.getInstance(key.getAlgorithm());
      this.dcipher = Cipher.getInstance(key.getAlgorithm());
      AlgorithmParameterSpec paramSpec = new PBEParameterSpec(this.salt, this.iterationCount);
      this.ecipher.init(1, key, paramSpec);
      this.dcipher.init(2, key, paramSpec);
          System.out.print("Cipher.getIV() original (byte[]) : " );
          for (int a=0;a<ecipher.getIV().length;a++) System.out.print(ecipher.getIV()[a]+" ");
          System.out.println("");
          System.out.println("Cipher.getBlockSize() : " + ecipher.getBlockSize());
          System.out.println("Cipher.getAlgorithm(): " + ecipher.getAlgorithm());
    } catch (Exception e) { }
  }
  public String encrypt(String aString) {
    try {
      byte[] utf8 = aString.getBytes("UTF8");
      byte[] enc = this.ecipher.doFinal(utf8);
      return new BASE64Encoder().encode(enc);
    } catch (Exception e) { }
    return null;
  }
  public String decrypt(String aString) {
    try {
      byte[] dec = new BASE64Decoder().decodeBuffer(aString);
      byte[] utf8 = this.dcipher.doFinal(dec);
      return new String(utf8, "UTF8");
    } catch (Exception e) { }
    return null;
  }
  public static void main(String[] args) {
    if (args.length == 0) {
      System.out.println("Usage: ");
      System.out.println("  java Encrypt <string>");
    } else {
      System.out.println("Orginal   string: " + args[0]);
      Encrypt encrypter = new Encrypt();
      String crypted = encrypter.encrypt(args[0]);
      String plain = encrypter.decrypt(args[0]);
      System.out.println("Crypted   string: " + crypted);
      System.out.println("Decrypted string: " + plain);
    }
  }
}

Codice: Seleziona tutto

$ java Encrypt Emanuele
Orginal   string: Emanuele
Cipher.getIV() original (byte[]) : 104 -49 -125 110 120 -64 -90 -79 
Cipher.getBlockSize() : 8
Cipher.getAlgorithm(): PBEWithMD5AndDES
Crypted   string: 8Mw36Qwue5+PB3HyoBzFNw==
Decrypted string: null

$ java Encrypt 8Mw36Qwue5+PB3HyoBzFNw==
Orginal   string: 8Mw36Qwue5+PB3HyoBzFNw==
Cipher.getIV() original (byte[]) : 104 -49 -125 110 120 -64 -90 -79 
Cipher.getBlockSize() : 8
Cipher.getAlgorithm(): PBEWithMD5AndDES
Crypted   string: r73sm6o8CZLdIjaLKd8dJhZaN9ZI2R42Em8adyQA/7Q=
Decrypted string: Emanuele
Packages finder: slakfinder.org | Slackpkg+, per aggiungere repository a slackpkg

Codice: Seleziona tutto

1011010 1100101 1110010 1101111 - 0100000 - 1010101 1101110 1101111

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6629
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: scoprire la chiave di cifratura

Messaggio da targzeta »

Effettivamente non ci sto capendo niente neanche io. Ho lascianto solo la parte di cifratura dal codice che hai postato:

Codice: Seleziona tutto

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;

import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;

import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

class Encrypt
{
    public static void main(String[] args)
    {
        Cipher ecipher;

        byte[] salt = { (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
                        (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08 };
        int iterationCount = 10;

        byte[] iv = {}, key = {};

        String  originalString = "Emanuele", password = "ottobyte",
            encryptedString = null;

        try
            {
                KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, iterationCount);

                SecretKey secretKey = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);

                ecipher = Cipher.getInstance(secretKey.getAlgorithm());

                AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);

                ecipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec);

                iv = ecipher.getIV();
                key = secretKey.getEncoded();
                encryptedString = new sun.misc.BASE64Encoder().encode(ecipher.doFinal(originalString.getBytes()));
            }
        catch (Exception e)
            {}

        System.out.println("Orginal string: " + originalString + "\n\nPassword  : " + password);
        printByte("Salt ", salt);
        System.out.println("Iter count: " + iterationCount + "\n");
        printByte("IV  ", iv);
        printByte("Key ", key);
        System.out.println("\nEncrypted string: " + encryptedString);
    }

    public static void printByte(String w, byte[] b)
    {
        int i;

        System.out.print(w + "(hex): ");
        for ( i = 0; i < 8; i++ )
            System.out.print(Integer.toHexString(b[i] & 0xFF));
        System.out.println("");
    }
}
Ho anche creato una funzione che "dovrebbe" stampare a video i byte in esadecimale (così come li vuole openssl) ed ho tentato di prelevare la chiave.

Però con openssl niente :evil:. Tra l'altro non mi torna una cosa:

Codice: Seleziona tutto

$> echo -n 'Emanuele' | openssl des-cbc -a -e -pass 'pass:ottobyte' -p -nosalt
key=FA868643C6F7A296
iv =E686E7D658809728
vKfS32uk1RWfWTnCtvz86Q==

$> echo 'vKfS32uk1RWfWTnCtvz86Q==' | openssl des-cbc -a -d -K 'FA868643C6F7A296' -iv 'E686E7D658809728'
Emanuele
e sembra corretto (non serve la password se conosci la chiave e l'iv). Però se faccio:

Codice: Seleziona tutto

$> echo -n 'Emanuele' | openssl des-cbc -a -e -pass 'pass:ottobyte' -p        
salt=5A8E23D01DE801B3
key=5E65DFCEE0A25AA7
iv =55FE1BFB7EE90706
U2FsdGVkX19ajiPQHegBs0XS8KZAoN6+K6w8sMFsr9U=

$> echo 'U2FsdGVkX19ajiPQHegBs0XS8KZAoN6+K6w8sMFsr9U=' | openssl des-cbc -a -d -K '5E65DFCEE0A25AA7' -iv '55FE1BFB7EE90706' -S '5A8E23D01DE801B3'
<stringa illegibile>
che poi secondo me non dovrebbe neanche servire il salt, ed in effetti anche senza il parametro '-S' ottengo la stessa stringa illegibile.

Emanuele
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

Rispondi