Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 18
  1. #1

    [JAVA] Crittografia Asimmetrica RSA

    Mi rivolgo a voi ancora una volta per un dilemma che mi affligge:
    Ho creato un'applicazione per la crittografia dei file,per quanto riguarda il metodo di sostituzione e trasposizione tutto ok , ma quando ho provato ad implementare l'RSA mi sono trovato in difficoltà.
    Creo la coppia di chiavi nel momento in cui vado a criptare.
    Uso la chiave pubblica per criptare il file e fin lì tutto ok.
    Quando devo decifrare il file crittografato parte un errore "Data must start with 0"
    Posto parti di codice per rendere il tutto più comprensibile:
    codice:
    // GENERA COPPIA DI CHIAVI
    	               
                    //Un reader per leggere la console
                    BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
                    System.out.print("Inizio generazione chiavi RSA");
                    //inizializza un generatore di coppie di chiavi usando RSA
                    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
                    System.out.print(".");
                    // le chiavi sono molto lunghe: 1024 bit sono 128 byte.
                    // La forza di RSA è nell'impossibilità pratica di fattorizzare
                    // numeri così grandi.
                    kpg.initialize(1024);
                    System.out.print(".");
                    // genera la coppia
                    KeyPair kp = kpg.generateKeyPair();
                    System.out.print(". Chiavi generate!\n");
                   
                    // SALVA CHIAVE PUBBLICA
                   
                    System.out.print("Inserire keystore per la chiave pubblica: ");
                    String publicKeystore = "C:\\Java Passwords\\chiavipubbliche.txt";
                    // ottieni la versione codificata in X.509 della chiave pubblica
                    // (senza cifrare)
                    byte[] publicBytes = kp.getPublic().getEncoded();
                    // salva nel keystore selezionato dall'utente
                    FileOutputStream fos = new FileOutputStream(publicKeystore);
                    fos.write(publicBytes);
                    fos.close();
                   
                    // SALVA CHIAVE PRIVATA
                   
                System.out.print("Inserire keystore per la chiave privata: ");
                    String privateKeystore = "C:\\Java Passwords\\chiaviprivate.txt";
                    // ottieni la versione codificata in PKCS#8
                    byte[] privateBytes = kp.getPrivate().getEncoded();
                   
                    fos = new FileOutputStream(privateKeystore);
                    fos.write(privateBytes);
                    fos.close();
                    
                    
                    
                    
                 // LEGGI CHIAVE PUBBLICA CODIFICATA IN X509
    	               
                    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                    System.out.print("Inserire keystore della chiave pubblica: ");
                    publicKeystore = "C:\\Java Passwords\\chiavipubbliche.txt";
                    FileInputStream fis = new FileInputStream(publicKeystore);
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    int i = 0;
                    while((i = fis.read()) != -1) {
                            baos.write(i);
                    }
                    fis.close();
                    byte[] publicKeyBytes = baos.toByteArray();
                    baos.close();
                   
                    // CONVERTI CHIAVE PUBBLICA DA X509 A CHIAVE UTILIZZABILE
                   
                    // Inizializza convertitore da X.509 a chiave pubblica
                    X509EncodedKeySpec ks = new X509EncodedKeySpec(publicKeyBytes);
                    // Inizializza un KeyFactory per ricreare la chiave usando RSA
                    KeyFactory kf = KeyFactory.getInstance("RSA");
                    // Crea una chiave pubblica usando generatePublic di KeyFactory in base la chiave decodificata da ks
                    PublicKey publicKey = kf.generatePublic(ks);
                    pubblica=publicKey;
    Per la parte del crittografare :

    codice:
    public static byte[] crypt(byte[] b,int c,PublicKey publicKey) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException{
    		 System.out.print("\nInizio codifica");
             // Inizializzo un cifrario che usa come algoritmo RSA, come modalità ECB e come padding PKCS1
             Cipher cifrario = Cipher.getInstance("RSA/ECB/PKCS1Padding");
             System.out.print(".");
             // Lo inizializzo dicendo modalità di codifica e chiave pubblica da usare
             cifrario.init(Cipher.ENCRYPT_MODE, publicKey);
             System.out.print(".");
             b=blockCipher(b,Cipher.ENCRYPT_MODE);
             // codifico e metto il risultato in encodeFile
             byte[] encodeFile = cifrario.doFinal(b);
             System.out.println(". Codifica terminata!");
             b= new byte[encodeFile.length];
             System.out.println("criptazione");
             c=encodeFile.length;
             b=encodeFile.clone();
    			return b;
    		}
    Nota importante*:b[] contiene un array di byte nudo e crudo ovvero una porzione di file letto così com'è

    Nel momento in cui devo decifrare il messaggio prendo il testo mediante
    codice:
    byte b[];
    				    	b=new byte[lByte];
    						int c=fis.read(b);
    					    while (c != -1){
    					    	b=select_decrypt(b,c,k);
    					    	out.write(b,0,c);
    					    	c= fis.read(b);
    					    }
    					    fis.close();
    					    out.flush();
    					    out.close();
    E poi parte (nel ciclo while) il decript che è:

    codice:
    public static byte[] decrypt(byte[] b,int c,Key privateKey) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException, IOException{
    
        	System.out.print("\nInizio decodifica");
             Cipher cifrario = Cipher.getInstance("RSA/ECB/PKCS1Padding");
             System.out.print(".");
             cifrario.init(Cipher.DECRYPT_MODE, privateKey);
             System.out.print(".");
             byte[] encodeFile = cifrario.doFinal(b);
             b= new byte[encodeFile.length];
             c=encodeFile.length;
             b=encodeFile.clone();
             System.out.println(". Decodifica terminata!");
    		return b;
    	}
    Lasciando perdere l'utilizzo inutile di variabili supporto ecc, non capisco perchè venga dato l'errore riportato all'inizio , l'unica cosa che mi viene in mente è che possa dipendere da una possibile formattazione del testo che necessita il cifrario
    L'errore è in byte[] encodeFile = cifrario.doFinal(b);

    Spero in una risposta anche perchè è molto importante per me riuscire a risolvere tale dilemma , se servono delucidazioni sul codice chiedete .
    Grazie in anticipo.

  2. #2
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    ho il dubbio che questo sia errato tenuto coonto della chiave che poi arriva


    Cipher cifrario = Cipher.getInstance("RSA/ECB/PKCS1Padding");


    prova solo con RSA

    mi sono espressa in modo contorto....
    quello che voglio dire è che se tu hai una chiave di tipo RSA, se chiedi un algoritmo di cifra con determinate modalità (es. il padding) devi avere dei parametri che sono conformi a quanto stai richiedendo).

    Ecco mi sorge il dubbio che cmq la tua chiave non sia conforme al padding richiesto. Per questo un tentativo lo farei usando solo RSA, per dirti di più posso fare altri controlli
    RTFM Read That F*** Manual!!!

  3. #3
    per semplificare tutto potrei scrivere il codice in questo modo (spero di non scrivere scemenze):

    codice:
     public static void codifica(String sorgenteFile,String destinazioneFile) throws Exception {
                   
                    // LEGGI CHIAVE PUBBLICA CODIFICATA IN X509
                   
                    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                    String publicKeystore = "C:\\Java Passwords\\chiavipubbliche.txt";
                    FileInputStream fis = new FileInputStream(publicKeystore);
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    int i = 0;
                    while((i = fis.read()) != -1) {
                            baos.write(i);
                    }
                    fis.close();
                    byte[] publicKeyBytes = baos.toByteArray();
                    baos.close();
                   
                    // CONVERTI CHIAVE PUBBLICA DA X509 A CHIAVE UTILIZZABILE
                   
                    // Inizializza convertitore da X.509 a chiave pubblica
                    X509EncodedKeySpec ks = new X509EncodedKeySpec(publicKeyBytes);
                    // Inizializza un KeyFactory per ricreare la chiave usando RSA
                    KeyFactory kf = KeyFactory.getInstance("RSA");
                    // Crea una chiave pubblica usando generatePublic di KeyFactory in base la chiave decodificata da ks
                    PublicKey publicKey = kf.generatePublic(ks);
                   
                    // LEGGI FILE SORGENTE
                   
                    String sorgente = sorgenteFile;
                    fis = new FileInputStream(sorgente);
                    baos.reset();
                    i=0;
                    String dest = destinazioneFile;
                    FileOutputStream fos = new FileOutputStream(dest);
                    while(i!=-1){
                    byte[] plainFile= new byte[64];
                    while((i = fis.read()) != -1 && i<plainFile.length) {
                            baos.write(i);
                    }
                    
                    plainFile = baos.toByteArray();
                   
                    // CODIFICA FILE SORGENTE
                    System.out.print("\nInizio codifica");
                    // Inizializzo un cifrario che usa come algoritmo RSA, come modalità ECB e come padding PKCS1
                    Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
                    System.out.print(".");
                    // Lo inizializzo dicendo modalità di codifica e chiave pubblica da usare
                    c.init(Cipher.ENCRYPT_MODE, publicKey);
                    System.out.print(".");
                    // codifico e metto il risultato in encodeFile
                    byte[] encodeFile = c.doFinal(plainFile);
                    System.out.println(". Codifica terminata!");
                   
                    // SALVA FILE CODIFICATO
    
                    fos.write(encodeFile);
                    }
                    fis.close();
                    fos.close();
            }
            
            public static void decodifica(String Filecodificato,String FiledaSalvare) throws Exception {
            	 
                // LEGGI CHIAVE PRIVATA CODIFICATA IN PKCS#8
               
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
               
                String privateKeystore = "C:\\Java Passwords\\chiaviprivate.txt";
                FileInputStream fis = new FileInputStream(privateKeystore);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                int i = 0;
                while((i = fis.read()) != -1) {
                        baos.write(i);
                }
                fis.close();
                byte[] privateKeyBytes = baos.toByteArray();
                baos.close();
               
                // CONVERTI CHIAVE PRIVATA PKCS8 IN CHIAVE NORMALE
               
                PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(privateKeyBytes);
                KeyFactory kf = KeyFactory.getInstance("RSA");
                PrivateKey privateKey = kf.generatePrivate(ks);
               
                // LEGGI FILE CODIFICATO
               
                
                String sorgente = Filecodificato;
                fis = new FileInputStream(sorgente);
                byte[] codFile = new byte[64];
                i = 0;
                String dest = FiledaSalvare;
                FileOutputStream fos = new FileOutputStream(dest);
                
                while(i!=-1){
                	 baos.reset();
                while((i = fis.read()) != -1 && i<codFile.length) {
                        baos.write(i);
                }
               
                codFile = baos.toByteArray();
               
        // DECODIFICA
               
                System.out.print("\nInizio decodifica");
                Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
                System.out.print(".");
                c.init(Cipher.DECRYPT_MODE, privateKey);
                System.out.print(".");
                byte[] plainFile = c.doFinal(codFile);
                System.out.println(". Decodifica terminata!");
               
                // SALVA FILE
    
                fos.write(plainFile);
                }
                fis.close();
                fos.close();
        }
    }
    l'errore che viene comunque fuori durante la decodifica è Data must start with zero O.o

    e se al posto di RSA/ecc metto solo RSA in questo esempio il risultato non cambia

  4. #4
    Ho provato a cambiare il metodo di scrittura e di lettura, ho provato a cambiare cifrari e padding ma nulla , sono senza idee

  5. #5
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    non preoccuparti che risolviamo.
    Non ho avuto tempo di dare un'occhio al tuo codice, se hai pazienza ti aiuto
    RTFM Read That F*** Manual!!!

  6. #6
    Si paziento , intanto mi metto sotto col cifrario di Vernam

  7. #7
    Scrivo questo messaggio con il solo scopo di dire che per ora non ho trovato nulla, perciò ogni aiuto è benvenuto , grazie a chi si sta interessando del problema.

  8. #8
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    Ok risolto, spet che ti posto il codice

    Codice PHP:

    import java
    .io.BufferedReader;
    import java.io.ByteArrayOutputStream;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.InputStreamReader;
    import java.security.InvalidKeyException;
    import java.security.KeyFactory;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.NoSuchAlgorithmException;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.Security;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.Arrays;

    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.NoSuchPaddingException;

    import org.bouncycastle.jce.provider.BouncyCastleProvider;

    public class 
    Example {

        public static 
    void main(String argsd[]) throws Exception {

            
    Security.addProvider(new BouncyCastleProvider());
            
    System.out.println("Inizio generazione chiavi RSA");
            
    // inizializza un generatore di coppie di chiavi usando RSA
            
    KeyPairGenerator kpg KeyPairGenerator.getInstance("RSA""BC");
            
    kpg.initialize(1024);
            
    KeyPair kp kpg.generateKeyPair();
            
    System.out.println("Chiavi generate!\n");

            
    // SALVA CHIAVE PUBBLICA
            
    String publicKeystore =//path
            
    byte[] publicBytes kp.getPublic().getEncoded();
            
    // salva nel keystore selezionato dall'utente
            
    FileOutputStream fos = new FileOutputStream(publicKeystore);
            
    fos.write(publicBytes);
            
    fos.close();

            
    // SALVA CHIAVE PRIVATA

            
    String privateKeystore =// path
            // ottieni la versione codificata in PKCS#8
            
    byte[] privateBytes kp.getPrivate().getEncoded();

            
    fos = new FileOutputStream(privateKeystore);
            
    fos.write(privateBytes);
            
    fos.close();

            
    // LEGGI CHIAVE PUBBLICA CODIFICATA IN X509
            
    FileInputStream fis = new FileInputStream(publicKeystore);
            
    byte[] publicKeyBytes = new byte[fis.available()];
            
            
    fis.read(publicKeyBytes);
            
            
    fis.close(); 
            
    // CONVERTI CHIAVE PUBBLICA DA X509 A CHIAVE UTILIZZABILE

            // Inizializza convertitore da X.509 a chiave pubblica
            
    X509EncodedKeySpec ks = new X509EncodedKeySpec(publicKeyBytes);
            
    // Inizializza un KeyFactory per ricreare la chiave usando RSA
            
    KeyFactory kf KeyFactory.getInstance("RSA""BC");
            
    // Crea una chiave pubblica usando generatePublic di KeyFactory in base
            // la chiave decodificata da ks
            
    PublicKey publicKey kf.generatePublic(ks);
            
    // pubblica = publicKey;
            
    byte[] temp crypt("Input message ".getBytes(), publicKey,
                    
    Cipher.ENCRYPT_MODE);

            
    byte[] out decrypt(temp,  kp.getPrivate());

            
    System.out.println(Arrays.equals("Input message".getBytes(), out));


        }

        public static 
    byte[] crypt(byte[] inputPublicKey publicKeyint mode)
                
    throws InvalidKeyExceptionNoSuchAlgorithmException,
                
    NoSuchPaddingExceptionIllegalBlockSizeException,
                
    BadPaddingException {
            
    System.out.print("\nInizio codifica");
            
    // Inizializzo un cifrario che usa come algoritmo RSA, come modalità ECB
            // e come padding PKCS1
            
    Cipher cifrario Cipher.getInstance("RSA/ECB/PKCS1Padding");
            
    System.out.print(".");
            
    // Lo inizializzo dicendo modalità di codifica e chiave pubblica da
            // usare
            
    cifrario.init(modepublicKey);
            
    System.out.print(".");
            
    // codifico e metto il risultato in encodeFile
            
    byte[] encodeFile cifrario.doFinal(input);
            
    System.out.println(". Codifica terminata!");
            
    input = new byte[encodeFile.length];
            
    System.out.println("cifratura");
            return 
    encodeFile;
        }

        public static 
    byte[] decrypt(byte[] inputPrivateKey privateKey)
                
    throws InvalidKeyExceptionNoSuchAlgorithmException,
                
    NoSuchPaddingExceptionIllegalBlockSizeException,
                
    BadPaddingException{

            
    System.out.print("\nInizio decodifica");
            
    Cipher cifrario Cipher.getInstance("RSA/ECB/PKCS1Padding");
            
    System.out.print(".");
            
    cifrario.init(Cipher.DECRYPT_MODEprivateKey);
            
    System.out.print(".");
            
    byte[] encodeFile cifrario.doFinal(input);
            
    System.out.println(". Decodifica terminata!");
            return 
    encodeFile;
        }

    da me funziona
    RTFM Read That F*** Manual!!!

  9. #9
    potresti spiegarmi una cosa? nella fase di decodifica come faccio a risalire alla chiave privata se il programma è stato chiuso? mi spiego meglio, dato che salvo chiave pubblica e privata in file distinti, e posso risalire alla pubblica , vale lo stesso discorso per la privata?


    Grazie della risposta, se riesco a implementarlo e funziona ti farò un monumento

  10. #10
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    allora fai conto che con algoritmi riguardanti la sicurezza si lavora SEMPRE SEMPRE coi byte array, il risultato dlele operazioni è un array di byte, in input hai array di byte.
    come vedi doFinal ritorna un array di byte, quello che devo portare all'esterno è proprio quest'output, senza elaborazioni non necessarie.
    Ecco perché ho preso in output quel valore e messo in temp.
    Questo è l'input della funzione di decifratura. Da questa in generale ho in outuput un array di byte.
    Per vedere se ho fatto bene devo confrontare il primo input con il risultato della decifratura
    RTFM Read That F*** Manual!!!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.