Repository 32bit  Forum
Repository 64bit  Wiki

[Java] Programma per criptare file

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
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.

[Java] Programma per criptare file

Messaggioda Porky » sab lug 25, 2009 22:43

Da un po' di tempo sto lavorando a questo programma per criptare file (e incredibilmente funziona \:D/ )
Il funzionamento è più o meno questo: vengono presi in input un file e una password (che più che una password è una "chiave"). La password viene tradotta carattere per carattere in byte, questi byte vengono sommati e il risultato viene ri-convertito in un byte. Dopodiché ogni singolo byte del file preso in input viene incrementato del valore del byte-password. Per decriptare i byte vengono decrementati dello stesso valore.
Funziona su qualunque tipo di file.

file KryptosMain.java:
Codice: Seleziona tutto
/*
Copyright 2008, 2009 Sebastiano Tronto <sebastiano@luganega.org>

This file is part of Kryptos.

    Kryptos is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    Kryptos is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Nome-Programma; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

*/

import java.util.Scanner;
import java.io.*;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class KryptosMain {
   public static int contatore;
   public static String pswd, percorso;
   public static byte[] percorsoConEstensione, percorsoSenzaEstensione;
   public static FileInputStream fileInput;
   public static FileOutputStream fileOutput;
   public static Scanner sc = new Scanner(System.in);
   public static KryptosFrame frame;
   public static void main ( String args[] ) {
      frame = new KryptosFrame();
      frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
      frame.setSize( 350, 150 );
      frame.setVisible( true );
   }
   public static void Cripta( String percorso, String password ) {
      try {
         contatore = 0;
         fileInput = new FileInputStream(percorso);
         byte[] arrayStringa = password.getBytes();
         for (int i = 0; i < arrayStringa.length; i++)
            contatore += arrayStringa[i];
         fileOutput = new FileOutputStream( percorso + ".krp" );
         byte[] byteNonModificati = new byte[fileInput.available()];
         fileInput.read( byteNonModificati );
         int[] byteModificati = new int[byteNonModificati.length];
         byte[] byteModificatiB = new byte[byteNonModificati.length];
         for ( int i=0; i<byteNonModificati.length; i++ ) {
            byteModificati[i] = (int)byteNonModificati[i] + contatore;
            byteModificatiB[i] = (byte)byteModificati[i];
         }
         fileOutput.write(byteModificatiB);
         JOptionPane.showMessageDialog( null, "Criptazione eseguita con succeso\n Il file criptato è:\n " + KryptosFrame.campoDiTesto.getText() + ".krp\n\nIl vecchio file NON è stato cancellato", "Kryptos - Informazione", JOptionPane.INFORMATION_MESSAGE );
      } catch ( FileNotFoundException e ) {
         JOptionPane.showMessageDialog( null, "Errore: file non trovato\naccertarsi di aver inserito il percorso corretto", "Kryptos - Errore", JOptionPane.ERROR_MESSAGE );
      } catch ( IOException e ) {
         JOptionPane.showMessageDialog( null, "Errore non previsto di Input/Output\nPer favore riportare il bug a sebastiano@luganega.org", "Kryptos - Errore", JOptionPane.ERROR_MESSAGE );
      } catch ( Exception e ) {
         JOptionPane.showMessageDialog( null, "Errore sconosciuto:\n\n" + e + "\n\nPer favore riportare il bug a sebastiano@luganega.org", "Kryptos - Errore", JOptionPane.ERROR_MESSAGE );
      }
   }
   public static void Decripta( String percorso, String password ) {
      try {
         contatore = 0;
         fileInput = new FileInputStream(percorso);
         byte[] arrayStringa = password.getBytes();
         percorsoConEstensione = percorso.getBytes();
         percorsoSenzaEstensione = new byte[percorsoConEstensione.length - 4];
         for ( int i = 0; i < percorsoSenzaEstensione.length; i++ )
            percorsoSenzaEstensione[i] = percorsoConEstensione[i];
         percorso = new String( percorsoSenzaEstensione );
         for ( int i = 0; i < arrayStringa.length; i++ )
            contatore += arrayStringa[i];
         fileOutput = new FileOutputStream( percorso );
         byte[] byteNonModificatiDec = new byte[fileInput.available()];
         fileInput.read(byteNonModificatiDec);
         int[] byteModificatiDec = new int[byteNonModificatiDec.length];
         byte[] byteModificatiBDec = new byte[byteNonModificatiDec.length];
         for (int i = 0; i < byteNonModificatiDec.length; i++) {
            byteModificatiDec[i] = (int)byteNonModificatiDec[i] - contatore;
            byteModificatiBDec[i] = (byte)byteModificatiDec[i];
         }
         fileOutput.write(byteModificatiBDec);
         JOptionPane.showMessageDialog( null, "Decriptazione eseguita con succeso\n Il file decriptato è:\n " + percorso + "\n\nIl vecchio file NON è stato cancellato", "Kryptos - Informazione", JOptionPane.INFORMATION_MESSAGE );
      } catch ( FileNotFoundException e ) {
         JOptionPane.showMessageDialog( null, "Errore: file non trovato\naccertarsi di aver inserito il percorso corretto", "Kryptos - Errore", JOptionPane.ERROR_MESSAGE );
      } catch ( IOException e ) {
         JOptionPane.showMessageDialog( null, "Errore non previsto di Input/Output\nPer favore riportare il bug a <html><i>sebastiano@luganega.org", "Kryptos - Errore", JOptionPane.ERROR_MESSAGE );
      } catch ( Exception e ) {
         JOptionPane.showMessageDialog( null, "Errore sconosciuto:\n\n" + e + "\n\nPer favore riportare il bug a <html><i>sebastiano@luganega.org", "Kryptos - Errore", JOptionPane.ERROR_MESSAGE );
      }
   }
}

file KryptosFrame.java:
Codice: Seleziona tutto
/*
Copyright 2008, 2009 Sebastiano Tronto <sebastiano@luganega.org>

This file is part of Kryptos.

    Kryptos is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    Kryptos is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Nome-Programma; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

*/

import javax.swing.*;
import javax.swing.filechooser.*;
import java.awt.*;
import java.awt.event.*;
public class KryptosFrame extends JFrame {
   private class Listener implements ActionListener {
      public void actionPerformed( ActionEvent e ) {
         if ( e.getSource() == Exit ) {
            System.exit(0);
         } else
         if ( e.getSource() == informazioni ) {
            JOptionPane.showMessageDialog( null, "Kryptos is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 2 of the License, or\n(at your option) any later version.\n\nKryptos is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with Nome-Programma; if not, write to the Free Software\nFoundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n\n<html><i>Copyright 2008, 2009 Sebastiano Tronto sebastiano@luganega.org</i></html>", "Kryptos - informazioni", JOptionPane.INFORMATION_MESSAGE );

         } else
         if ( e.getSource() == selezione ) {
            switch ( selezione.getSelectedIndex() ) {
               case 0:
                  chooser.removeChoosableFileFilter( filter );
                  chooser.removeChoosableFileFilter( chooser.getAcceptAllFileFilter() );
                  chooser.addChoosableFileFilter( chooser.getAcceptAllFileFilter() );
                  break;
               case 1:
                  chooser.addChoosableFileFilter( filter );
                  break;
            }
         } else
         if ( e.getSource() == sfoglia ) {
            valoreChooser = chooser.showOpenDialog( KryptosMain.frame );
            switch ( valoreChooser ) {
               case JFileChooser.APPROVE_OPTION:
                  campoDiTesto.setText( chooser.getSelectedFile().getPath() );
                  break;
               case JFileChooser.ERROR_OPTION:
                  JOptionPane.showMessageDialog( null, "Errore sconosciuto:\n\n" + e + "\n\nPer favore riportare il bug a sebastiano@luganega.org", "Kryptos - Errore", JOptionPane.ERROR_MESSAGE );
                  break;
               //case JFileChooser.CANCEL_OPTION:
            }
         } else
         if ( e.getSource() == vai || e.getSource() == campoDiTesto || e.getSource() == campoPassword ) {
            if ( campoPassword.getText().equals( "" ) )
               JOptionPane.showMessageDialog( null, "Password non impostata: è necessaria una password come ''chiave'' per la criptazione/decriptazione del file", "Kryptos - Avviso", JOptionPane.WARNING_MESSAGE );
            switch ( selezione.getSelectedIndex() ) {
               case 0:
                  KryptosMain.Cripta( campoDiTesto.getText(), campoPassword.getText() );
                  break;
               case 1:
                  KryptosMain.Decripta( campoDiTesto.getText(), campoPassword.getText() );
                  break;
            }
         }
      }
   }
   Listener listener = new Listener();
   KryptosMain main = new KryptosMain();
   JFileChooser chooser = new JFileChooser();
   public static JPanel pannelli[] = new JPanel[3];
   public static JLabel testo1, testo2, testo3;
   public static JTextField campoDiTesto;
   public static JPasswordField campoPassword;
   public static JButton sfoglia, vai;
   public static JComboBox selezione;
   public static FileNameExtensionFilter filter = new FileNameExtensionFilter( "File KRP", "krp" );
   public static String arraySelezione[] = { "Cripta", "Decripta" };
   public static boolean boolSelezione = true;
   public static int valoreChooser;
   public static MenuBar barraMenu = new MenuBar();
   public static Menu file = new Menu( "File" );
   public static Menu info = new Menu( "?" );
   public static MenuItem Exit = new MenuItem( "Esci" );
   public static MenuItem informazioni = new MenuItem( "Informazioni" );
   public KryptosFrame() {
      super( "Porky's Kryptos - versione 3.2" );
      setMenuBar( barraMenu );
      barraMenu.add( file );
      barraMenu.add( info );
      file.add( Exit );
      info.add( informazioni );
      Exit.addActionListener( listener );
      informazioni.addActionListener( listener );
      for ( int i = 0; i < pannelli.length; i++ )
         pannelli[i] = new JPanel();
      pannelli[0].setLayout( new FlowLayout() );
      add( pannelli[0], BorderLayout.NORTH );
      pannelli[1].setLayout( new FlowLayout() );
      add( pannelli[1], BorderLayout.CENTER );
      pannelli[2].setLayout( new FlowLayout() );
      add( pannelli[2], BorderLayout.SOUTH );
      testo1 = new JLabel( "Benvenuti in Kryptos, Il criptatore!" );
      testo2 = new JLabel( "File:          " );
      testo3 = new JLabel( "Password: " );
      campoDiTesto = new JTextField( "Inserire il percorso del file", 15 );
      campoPassword = new JPasswordField( 9 );
      sfoglia = new JButton( "Sfoglia" );
      vai = new JButton( "Vai!" );
      selezione = new JComboBox( arraySelezione );
      pannelli[0].add( testo1 );
      pannelli[1].add( testo2 );
      pannelli[1].add( campoDiTesto );
      pannelli[1].add( sfoglia );
      pannelli[2].add( testo3 );
      pannelli[2].add( campoPassword );
      pannelli[2].add( selezione );
      pannelli[2].add( vai );
      sfoglia.addActionListener( listener );
      vai.addActionListener( listener );
      campoDiTesto.addActionListener( listener );
      campoPassword.addActionListener( listener );
      selezione.addActionListener( listener );
   }
}

Download: qui
una volta scaricato il file eseguite Esegui.bat (windos) o Esegui.sh (Linux (dopo aver dato al file i permessi di esecuzione) )
Versione testuale (stesso identico funzionamento ma senza grafica): http://porkynator.altervista.org/Kryptos-2.0.zip
Si accettano commenti/critiche/altro
Avatar utente
Porky
Linux 2.0
Linux 2.0
 
Messaggi: 104
Iscritto il: mer lug 23, 2008 19:52
Località: Belluno
Nome Cognome: Sebastiano Tronto
Slackware: 13.37
Desktop: KDE

Re: [Java] Programma per criptare file

Messaggioda masalapianta » sab lug 25, 2009 23:14

E' praticamente il cifrario di Cesare
Avatar utente
masalapianta
Iper Master
Iper Master
 
Messaggi: 2775
Iscritto il: dom lug 24, 2005 23:00
Località: Roma
Nome Cognome: famoso porco
Kernel: uname -r
Desktop: awesome
Distribuzione: Debian

Re: [Java] Programma per criptare file

Messaggioda kreen » sab lug 25, 2009 23:58

Ciao.
Su cosa ti interessano i commenti?
Avatar utente
kreen
Linux 2.4
Linux 2.4
 
Messaggi: 228
Iscritto il: mer feb 01, 2006 18:32
Località: Verona
Slackware: 12.0
Kernel: 2.6.21.5-smp
Desktop: KDE

Re: [Java] Programma per criptare file

Messaggioda Porky » dom lug 26, 2009 8:17

masalapianta ha scritto:E' praticamente il cifrario di Cesare


è vero non lo conoscevo... comunque funziona su tutti i tipi di file, perché opera sui byte

kreen ha scritto:Ciao.
Su cosa ti interessano i commenti?


Su qualunque cosa, soprattutto se il codice è pulito, se ci sono cose che posso migliorare, ecc...
Avatar utente
Porky
Linux 2.0
Linux 2.0
 
Messaggi: 104
Iscritto il: mer lug 23, 2008 19:52
Località: Belluno
Nome Cognome: Sebastiano Tronto
Slackware: 13.37
Desktop: KDE

Re: [Java] Programma per criptare file

Messaggioda raffaele181188 » dom lug 26, 2009 9:53

Essendo per la maggior parte GUI, non penso che la pulizia dovrebbe interessarti più di tanto. Considera che Swing e tutto quello che ci sta sotto (tipo i Beans) sono stati inventati per offrire una API ai creatori di tool per generare API. Scrivere una finestrella a mano con Swing è
  • Ostico
  • Noioso
  • Una perdita enorme di tempo
  • Contro i principi del linguaggio
Il problema è che, scrivendo a mano, è difficile usare roba tipo il GridBag, e posizionare e allineare correttamente gli elementi. Si perdono ore, che si dovrebbero dedicare ad altro. Per esempio alla scelta dell'algoritmo di cifratura. Come ti diceva Masa è un Caesar shift. Per aggiungere qualcosa di mio, ti faccio notare che il metodo che hai scelto è soggetto a tutte le vulnerabilità che trovi sulle pagine di spiegazione, quindi non è un algoritmo usato da nessuna parte. Inoltre, e cosa ben più grave, la "chiave di cifratura" viene, se ho inteso correttamente, dalla somma dei codici ASCII associati ad ogni carattere. Giusto? In tal caso ogni anagramma porta alla stessa "chiave" (tipo notizia e tiziano, giusto perchè sono in una canzone che si sente spesso :D ), ma anche parole che non c'entrano niente tra di loro, ed hanno lunghezza diversa e caratteri diversi, possono portare alla stessa "chiave", persino stringhe casuali, ma pure parole reali tipo, non saprei, "zorro", "Sdf78sdf" e "abbecedario", se la somma dei codici ASCII fosse la stessa.. Ora non ho tempo per scriverti un programma di test. Praticamente si può "bucare" pure sbagliando password. Insomma, la parte "logica" dell'applicazione, per me, è da riscrivere completamente, nel senso che di fatto questo metodo non critta niente, è troppo vulnerabile.
Sulla parte linguistica
Non so a che livello sei, ma mi piace moltissimo il tuo modo di scrivere, esemplarmente chiaro. Ottima scelta per i nomi delle variabili e per tante altre cose. Mi è bastato leggere il codice una sola volta, non sono mai tornato indietro. Quindi, da questo punto di vista, sei stato molto bravo. Questi sono i miei appunti, vedi tu se sei d'accordo
  • password e contatore sono gestiti "stranamente", visto che sono parametri di critta() e decritta() e anche membri dell'oggeto (a proposito, i nomi dei metodi per convenzione sono minuscoli e camel cased)
  • I file possono anche non avere estensione (o avere estensioni diverse da tre caratteri), non credi?
  • Se hai studiato i thread puoi applicarli a questo esercizio e vedere quanto migliorano le prestazioni. Può servirti in futuro a comprenderne le potenzialità
Replica pure se non sei d'accordo :D
Avatar utente
raffaele181188
Packager
Packager
 
Messaggi: 789
Iscritto il: ven set 07, 2007 20:40
Località: DearSkin (FG)
Nome Cognome: Raffaele
Slackware: current
Kernel: 2.6.29.6
Desktop: KDE 4.3
Distribuzione: Ubuntu

Re: [Java] Programma per criptare file

Messaggioda Porky » dom lug 26, 2009 10:47

Grazie dei consigli, ma penso che tu mi abbia un po' SOPRAvvalutato... io programmo per passatempo quando non ho niente da fare, quindi non sono a chissà che livello... praticamente ogni "programma" che scrivo lo faccio per provare alcune cose che ho appena imparato leggendole da qualche parte...
raffaele181188 ha scritto:Essendo per la maggior parte GUI, non penso che la pulizia dovrebbe interessarti più di tanto. Considera che Swing e tutto quello che ci sta sotto (tipo i Beans) sono stati inventati per offrire una API ai creatori di tool per generare API. Scrivere una finestrella a mano con Swing è
  • Ostico
  • Noioso
  • Una perdita enorme di tempo
  • Contro i principi del linguaggio
Il problema è che, scrivendo a mano, è difficile usare roba tipo il GridBag, e posizionare e allineare correttamente gli elementi. Si perdono ore, che si dovrebbero dedicare ad altro.


Come ho già detto, programmo per prova, per imparare, quindi mi piace scrivere tutto il codice a mano senza usare tool di nessun genere: solo kwrite e tanto tempo da buttare in errori stupidi :lol:

Per esempio alla scelta dell'algoritmo di cifratura. Come ti diceva Masa è un Caesar shift. Per aggiungere qualcosa di mio, ti faccio notare che il metodo che hai scelto è soggetto a tutte le vulnerabilità che trovi sulle pagine di spiegazione, quindi non è un algoritmo usato da nessuna parte. Inoltre, e cosa ben più grave, la "chiave di cifratura" viene, se ho inteso correttamente, dalla somma dei codici ASCII associati ad ogni carattere. Giusto? In tal caso ogni anagramma porta alla stessa "chiave" (tipo notizia e tiziano, giusto perchè sono in una canzone che si sente spesso :D ), ma anche parole che non c'entrano niente tra di loro, ed hanno lunghezza diversa e caratteri diversi, possono portare alla stessa "chiave", persino stringhe casuali, ma pure parole reali tipo, non saprei, "zorro", "Sdf78sdf" e "abbecedario", se la somma dei codici ASCII fosse la stessa.. Ora non ho tempo per scriverti un programma di test. Praticamente si può "bucare" pure sbagliando password. Insomma, la parte "logica" dell'applicazione, per me, è da riscrivere completamente, nel senso che di fatto questo metodo non critta niente, è troppo vulnerabile.


Prossimamente ci lavorerò su... per il momento non pretendo che sia un programma perfetto, mi basta che funzioni.
Non sapevo nemmeno dell'esistenza del cifrario di Cesare fino a ieri (eh sì lo so, sono un ignorante... :D ), questo era semplicemente il primo modo che mi era venuto in mente per criptare un file. Addirittura nella prima versione di questo programmino non c'era nemmeno una password, ogni byte veniva incrementato semplicemente di 1; più che altro era una prova per vedere se operavo correttamente su i file.

Sulla parte linguistica
Non so a che livello sei, ma mi piace moltissimo il tuo modo di scrivere, esemplarmente chiaro. Ottima scelta per i nomi delle variabili e per tante altre cose. Mi è bastato leggere il codice una sola volta, non sono mai tornato indietro. Quindi, da questo punto di vista, sei stato molto bravo.


Grazie :) Cerco di essere chiaro quando scrivo soprattutto per riuscire a capire il codice se lo riguardo tra qualche anno...

Questi sono i miei appunti, vedi tu se sei d'accordo
password e contatore sono gestiti "stranamente", visto che sono parametri di critta() e decritta() e anche membri dell'oggeto (a proposito, i nomi dei metodi per convenzione sono minuscoli e camel cased)


dovrei mettere un po' di ordine forse :-k

I file possono anche non avere estensione (o avere estensioni diverse da tre caratteri), non credi?


solo il metodo Decripta() toglie l'estensione perché ho pensato che, normalmente, dovrebbe operare solo su file con estensione .krp (cioè quelli precedentemente criptati con il metodo Cripta() )

Se hai studiato i thread puoi applicarli a questo esercizio e vedere quanto migliorano le prestazioni. Può servirti in futuro a comprenderne le potenzialità
Replica pure se non sei d'accordo :D


Non ci avevo pensato... non li ho studiati molto bene, questa è una buona scusa per ripassarli :thumbright:
Avatar utente
Porky
Linux 2.0
Linux 2.0
 
Messaggi: 104
Iscritto il: mer lug 23, 2008 19:52
Località: Belluno
Nome Cognome: Sebastiano Tronto
Slackware: 13.37
Desktop: KDE


Torna a Programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite