Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it L'avatar di Cool81
    Registrato dal
    Dec 2008
    Messaggi
    160

    Criptare e decriptare password

    Ho il seguente problema: ogni utente ha un password che, a discrezione dell'utente stesso, può essere salvata e quindi scritta su un file che contiene tutte le proprietà del profilo di quell'utente.
    Ho quindi la prima necessità di criptare la password da salvare.

    Ho poi la seconda necessità di decriptare la password dopo averla letta dal file medesimo per motivi di autenticazione con un webservice.


    Ho cercato su internet e su questo forum, ed in quest'ultimo ho trovato il seguente codice riportata in una vecchia discussione:

    codice:
    import java.security.spec.*;
    import javax.crypto.*;
    import javax.crypto.spec.*;
    import java.io.*;
    
    public class Crypt {
      Cipher ecipher;
      Cipher dcipher;
      
      // 8-byte Salt
      byte[] salt = {(byte)0xA9, (byte)0x9B, (byte)0xC8, (byte)0x32,
                    (byte)0x56, (byte)0x35, (byte)0xE3, (byte)0x03
      };
      
      // Iteration count
      int iterationCount = 19;
      
      public Crypt(String passPhrase) {
        try {
          // Create the key
          KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
          SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
          ecipher = Cipher.getInstance(key.getAlgorithm());
          dcipher = Cipher.getInstance(key.getAlgorithm());
    
          // Prepare the parameter to the ciphers
          AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
      
          // Create the ciphers
          ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
          dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
        } catch (java.security.InvalidAlgorithmParameterException e) {
        } catch (java.security.spec.InvalidKeySpecException e) {
        } catch (javax.crypto.NoSuchPaddingException e) {
        } catch (java.security.NoSuchAlgorithmException e) {
        } catch (java.security.InvalidKeyException e) {
        }
      }
      
      public String encrypt(String str) {
        try {
          // Encode the string into bytes using utf-8
          byte[] utf8 = str.getBytes("UTF8");
      
          // Encrypt
          byte[] enc = ecipher.doFinal(utf8);
      
          // Encode bytes to base64 to get a string
          return new sun.misc.BASE64Encoder().encode(enc);
        } catch (javax.crypto.BadPaddingException e) {
        } catch (IllegalBlockSizeException e) {
        } catch (UnsupportedEncodingException e) {
        } catch (java.io.IOException e) {
        }
        return null;
      }
      
      public String decrypt(String str) {
        try {
          // Decode base64 to get bytes
          byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
      
          // Decrypt
          byte[] utf8 = dcipher.doFinal(dec);
      
          // Decode using utf-8
          return new String(utf8, "UTF8");
        } catch (javax.crypto.BadPaddingException e) {
        } catch (IllegalBlockSizeException e) {
        } catch (UnsupportedEncodingException e) {
        } catch (java.io.IOException e) {
        }
        return null;
      }
    }

    Prendendo spunto da questo codice, ho cercato di adeguarlo alle mie esigenze, in questo modo:

    codice:
    public class Crypt {
    
        Cipher ecipher;
        Cipher dcipher;
    
        // 8-byte Salt
        byte[] salt = {(byte)0xA9, (byte)0x9B, (byte)0xC8, (byte)0x32,
                        (byte)0x56, (byte)0x35, (byte)0xE3, (byte)0x03
                       };
    
        // Iteration count
        int iterationCount = 19;
        
        public Crypt(){};
    
          public String encrypt(String str) {
            try {
    
              // Create the key
                KeySpec keySpec = null;
              for(int i=0; i < 100; i++){
                  keySpec = new PBEKeySpec(str.toCharArray(), salt, iterationCount);
                  System.out.println("La keySpec è " + keySpec);
              }
              
              SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
              ecipher = Cipher.getInstance(key.getAlgorithm());
              dcipher = Cipher.getInstance(key.getAlgorithm());
    
              // Prepare the parameter to the ciphers
              AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
    
              // Create the ciphers
              ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
             //dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
            } catch (java.security.InvalidAlgorithmParameterException e) {
            } catch (java.security.spec.InvalidKeySpecException e) {
            } catch (javax.crypto.NoSuchPaddingException e) {
            } catch (java.security.NoSuchAlgorithmException e) {
            } catch (java.security.InvalidKeyException e) {
            }
            try {
              // Encode the string into bytes using utf-8
              byte[] utf8 = str.getBytes("UTF8");
    
              // Encrypt
              byte[] enc = ecipher.doFinal(utf8);
    
              // Encode bytes to base64 to get a string
              return new sun.misc.BASE64Encoder().encode(enc);
            } catch (javax.crypto.BadPaddingException e) {
            } catch (IllegalBlockSizeException e) {
            } catch (UnsupportedEncodingException e) {
            } catch (java.io.IOException e) {
            }
            return null;
          }
    
          public String decrypt(String str) {
    
             try {
              // Create the key
              KeySpec keySpec = new PBEKeySpec(str.toCharArray(), salt, iterationCount);
              SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
    //          ecipher = Cipher.getInstance(key.getAlgorithm());
              dcipher = Cipher.getInstance(key.getAlgorithm());
    
              // Prepare the parameter to the ciphers
              AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
    
              // Create the ciphers
    //          ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
              dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
            } catch (java.security.InvalidAlgorithmParameterException e) {
            } catch (java.security.spec.InvalidKeySpecException e) {
            } catch (javax.crypto.NoSuchPaddingException e) {
            } catch (java.security.NoSuchAlgorithmException e) {
            } catch (java.security.InvalidKeyException e) {
            }
            try {
              // Decode base64 to get bytes
              byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
    
              // Decrypt
              byte[] utf8 = dcipher.doFinal(dec);
    
              // Decode using utf-8
              return new String(utf8, "UTF8");
            } catch (javax.crypto.BadPaddingException e) {
            } catch (IllegalBlockSizeException e) {
            } catch (UnsupportedEncodingException e) {
            } catch (java.io.IOException e) {
            }
            return null;
          }
    In questo modo mi salva sul file la password criptata, ma quando cerco di decriptarla, mi restituisce null.

    Qualcuno mi può aiutare a capire come devo modificare questo codice in base a quello che serve a me?

  2. #2
    Utente di HTML.it
    Registrato dal
    Aug 2002
    Messaggi
    8,013
    non fai alcuna gestione delle eccezioni: probabilmente ce n'è almeno una che viene sollevata e non gestita e non ritorna mai quanto nel blocco try. Comincia a farti stampare quanto meno lo StackTrace in ciascun catch....
    <´¯)(¯`¤._)(¯`»ANDREA«´¯)(_.¤´¯)(¯`>
    "The answer to your question is: welcome to tomorrow"

  3. #3
    Utente di HTML.it L'avatar di Cool81
    Registrato dal
    Dec 2008
    Messaggi
    160
    Il printStackTrace() mi stampa la seguente eccezione:

    codice:
    javax.crypto.BadPaddingException: Given final block not properly padded
            at com.sun.crypto.provider.SunJCE_h.b(DashoA12275)
            at com.sun.crypto.provider.SunJCE_h.b(DashoA12275)
            at com.sun.crypto.provider.SunJCE_af.b(DashoA12275)
            at com.sun.crypto.provider.PBEWithMD5AndDESCipher.engineDoFinal(DashoA12275)
            at javax.crypto.Cipher.doFinal(DashoA12275)
    Cosa significa?

    Anche se so che non è il metodo più sicuro, è possibile definire una chiave, quindi un'oggetto Key o KeyGenerator come una costante?

    Sulla documentazione ho trovato questo metodo che serve ad inizializzare l'oggetto in questione:

    codice:
    init
    
    public final void init(SecureRandom random)
    
        Initializes this key generator.
    
        Parameters:
            random - the source of randomness for this generator
    Ma nn riesco a capire bene come scrivere il codice, perchè così nn va bene:

    codice:
    private static final KeyGenerator KEY = KeyGenerator.init(new SecureRandom().getInstance("SHA1PRNG"));
    Avete qualche idea?

  4. #4
    Utente di HTML.it L'avatar di Cool81
    Registrato dal
    Dec 2008
    Messaggi
    160
    Alle prese sempre con lo stesso problema, ho trovato quest'altro codice fatto da un utente del forum:

    codice:
    import java.io.UnsupportedEncodingException;
    
    public class Crypt2
    {
    	private static final String [] DEFAULT_KEYS = {
    		"01210ACB39201293948ABE4839201CDF",
    		"123219843895AFDE3920291038103839",
    		"89128912093908120983980981098309",
    		"AABBCCDD019201920384383728298109"
    	};
    	private static boolean updatedProps = false;
    	private static final char[] hexDigits = {
    		'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
    	};
    
    	private byte [][] keys = null;
    
    	public Crypt2() {
    		init(this.DEFAULT_KEYS);
    	}
    
    	public Crypt2(String [] keystrs) {
    		init(keystrs);
    	}
    
    	private void init(String [] keystrs) {
    		keys = new byte[keystrs.length][];
    		for (int i = 0; i < keys.length; i++) {
    			keys[i] = fromString(keystrs[i]);
    		}
    	}
    
    	private String toString(byte[] ba) {
    		char[] buf = new char[ba.length * 2];
    		int j = 0;
    		int k;
    
    		for (int i = 0; i < ba.length; i++) {
    			k = ba[i];
    			buf[j++] = hexDigits[(k >>> 4) & 0x0F];
    			buf[j++] = hexDigits[ k        & 0x0F];
    		}
    		return new String(buf);
    	}
    
    	private int fromDigit(char ch) {
    		if (ch >= '0' && ch <= '9')
    			return ch - '0';
    		if (ch >= 'A' && ch <= 'F')
    			return ch - 'A' + 10;
    		if (ch >= 'a' && ch <= 'f')
    			return ch - 'a' + 10;
    
    		throw new IllegalArgumentException("invalid hex digit '" + ch + "'");
    	}
    
    	private byte[] fromString(String hex) {
    		int len = hex.length();
    		byte[] buf = new byte[((len + 1) / 2)];
    
    		int i = 0, j = 0;
    		if ((len % 2) == 1)
    			buf[j++] = (byte) fromDigit(hex.charAt(i++));
    
    		while (i < len) {
    			buf[j++] = (byte) ((fromDigit(hex.charAt(i++)) << 4) |
    								fromDigit(hex.charAt(i++)));
    		}
    		return buf;
    	}
    
    	private byte encrypt(byte d, byte [] key) {
    		byte e;
    
    		e = d;
    		for (int i = 0; i < key.length; i++) {
    			e = (byte) ((int) e ^ (int) key[i]);
    		}
    
    		return e;
    	}
    
    	private byte decrypt(byte e, byte [] key) {
    		byte d;
    
    		d = e;
    		for (int i = key.length-1; i >= 0; i--) {
    			d = (byte) ((int) d ^ (int) key[i]);
    		}
    
    		return d;
    	}
    
    	public String encrypt(String orig) {
    		byte [] ect = null;
    		int size;
    		byte [] origBytes = null;
    
    		try {
    			origBytes = orig.getBytes("UTF-8");
    		} catch (UnsupportedEncodingException e) {
    			e.printStackTrace();
    			throw new RuntimeException(e.toString());
    		}
    
    		ect = new byte[origBytes.length];
    		for (int i = 0; i < origBytes.length; i += keys.length) {
    			for (int j = 0; j < keys.length; j++) {
    				if ((i+j) >= origBytes.length) {
    					break;
    				} else {
    					ect[i+j] = encrypt(origBytes[i+j], keys[j]);
    				}
    			}
    		}
    
    		return toString(ect);
    	}
    
    	public String decrypt(String ectstr) {
    		byte [] ect = null;
    		int size;
    		byte [] origBytes = null;
    		String dctStr = null;
    
    		ect = fromString(ectstr);
    		origBytes = new byte[ect.length];
    		for (int i = 0; i < origBytes.length; i += keys.length) {
    			for (int j = 0; j < keys.length; j++) {
    				if ((i+j) >= origBytes.length) {
    					break;
    				} else {
    					origBytes[i+j] = decrypt(ect[i+j], keys[j]);
    				}
    			}
    		}
    
    		try {
    			dctStr = new String(origBytes, "UTF-8");
    		} catch (UnsupportedEncodingException e) {
    			e.printStackTrace();
    			throw new RuntimeException(e.toString());
    		}
    		return dctStr;
    	}
    
    }

    Quando provo a decriptare mi lancia questa eccezione:

    codice:
    Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: invalid hex digit 'Y'
    Dove Y è un carattere della parola da decriptare.
    Ho cercato su internet di capire cosa è questa eccezione e quindi di capire se riesco a dare una soluzione, ma niente.

    Illuminatemiiiiiiiiiii............................ ...

  5. #5
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,315
    Originariamente inviato da Cool81
    Quando provo a decriptare mi lancia questa eccezione:

    codice:
    Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: invalid hex digit 'Y'
    Dove Y è un carattere della parola da decriptare.
    Ho cercato su internet di capire cosa è questa eccezione e quindi di capire se riesco a dare una soluzione, ma niente.

    Illuminatemiiiiiiiiiii............................ ...
    Questo è dovuto a questa parte di codice:

    codice:
    	private int fromDigit(char ch) {
    		if (ch >= '0' && ch <= '9')
    			return ch - '0';
    		if (ch >= 'A' && ch <= 'F')
    			return ch - 'A' + 10;
    		if (ch >= 'a' && ch <= 'f')
    			return ch - 'a' + 10;
    
    		throw new IllegalArgumentException("invalid hex digit '" + ch + "'");
    	}
    Ed è corretto... Y non è un carattere valido per un valore esadecimale (i caratteri validi sono nell'intervallo [0-9,A-F].

    Quel metodo viene richiamato dal metodo fromString(), che a sua volta è richiamato proprio nella decrypt().


    Perchè nella parola criptata sia uscita una Y, non lo so: non ho guardato la classe, né il suo funzionamento, né ciò che ci si aspetta come output da una chiamata a encrypt().


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  6. #6
    Utente di HTML.it L'avatar di Cool81
    Registrato dal
    Dec 2008
    Messaggi
    160

    Eccezione: javax.crypto.BadPaddingException: Given final block not properly padded

    Ciao....no, ancora nn ho risolto...

    Il problema è sempre lo stesso: criptare e decriptare un psw.
    Adesso sto usando questa classe:

    codice:
    import java.io.UnsupportedEncodingException;
    import javax.crypto.*;
    import javax.crypto.Cipher;
    import java.security.*;
    import javax.crypto.KeyGenerator;
    
    public class CryptoStringUtil
    {
        private Key key = null;
    
        public CryptoStringUtil(){
            initKey();
        }
    
        private void initKey(){
            // -------- creazione generatore di chiavi------------------------
            System.out.println("Creazione del generatore di chiavi");
            KeyGenerator gen = null;
            try {
                gen = KeyGenerator.getInstance("DES");
            }catch (NoSuchAlgorithmException e1) {
                System.out.println("Algoritmo non supportato in KeyGenerator");
                System.exit(1);
            }
    
            System.out.println("Generatore di chiavi creato.");
    
            // -------- generazione chiave ------------------------------------
            System.out.println("Generazione della chiave segreta");
    
            gen.init(new SecureRandom());
            Key k = gen.generateKey();
    
            System.out.println("Chiave generata: ");
    
            for (int i=0; i<k.getEncoded().length; i++)
                System.out.print("" + k.getEncoded()[i] + "\t");
    
            System.out.println("");
            this.key = k;
        }
    
        public Key getKey(){
            return key;
        }
        
        public String criptaPassword(String password, Key key) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException{
    
            // -------- creazione Cifratore -----------------
            System.out.println("Generazione del Cipher per l'algoritmo prescelto");
            Cipher des =  null;
            try {
                des = Cipher.getInstance("DES");
            }catch(Exception e){
                e.printStackTrace();
            }
    
            // -------- cifratura  ------------------------------------
            
            byte[] dataPsw = password.getBytes("utf-8");
            System.out.println("Messaggio in chiaro: ");
            for (int i=0; i<dataPsw.length; i++)
                System.out.print("" + dataPsw[i] + "\t");
            System.out.println("");
    
            
            // ----- inizializzazione per cifratura --------
            des.init(Cipher.ENCRYPT_MODE, key);
            System.out.println("Cipher inizializzato per cifratura");
    
            // -------- cifratura -------------------
            byte[] dataPsw_criptata = des.doFinal(dataPsw);
            String psw_criptata = new String(dataPsw_criptata);
    	    System.out.println("");
            return psw_criptata;
        }
    
    
        public String decriptPassword(String password_criptata, Key key){
    
             // -------- creazione Cifratore -----------------
            System.out.println("Generazione del Cipher per l'algoritmo prescelto");
            Cipher des =  null;
            try {
                des = Cipher.getInstance("DES");
            }catch(Exception e){
                e.printStackTrace();
            }
    
            try{
    	   // ----- inizializzazione per decifratura --------
            des.init(Cipher.DECRYPT_MODE, key);
            System.out.println("Cipher inizializzato per decifratura");
    
            // -------- decifratura ----------------
            byte[] newdata_psw = password_criptata.getBytes();
            byte[] dataPsw_decriptata = des.doFinal(newdata_psw);
    
    	    System.out.println("Messaggio decifrato: ");
    
    	    String psw_decriptata = new String(dataPsw_decriptata);
    	    System.out.println("");
            return psw_decriptata;
    	
            }catch (BadPaddingException e) {
                e.printStackTrace();
                System.out.println("Bad Padding");
            }catch (InvalidKeyException e) {
                e.printStackTrace();
                System.out.println("Chiave non valida");
            }catch (IllegalBlockSizeException e) {
                e.printStackTrace();
                System.out.println("Dimensione del blocco illegale");
            }
            return null;
      }
    }
    e mi lancia eccezione qui
    codice:
    des.doFinal(newdata_psw);
    L'eccezione è la seguente:

    codice:
    javax.crypto.BadPaddingException: Given final block not properly padded
            at com.sun.crypto.provider.SunJCE_h.b(DashoA12275)
            at com.sun.crypto.provider.SunJCE_h.b(DashoA12275)
            at com.sun.crypto.provider.DESCipher.engineDoFinal(DashoA12275)
            at javax.crypto.Cipher.doFinal(DashoA12275)
           ...
    Su internet ho trovato che può dipendere dal fatto che converto una stringa in un array di byte, ma non riesco a trovare una soluzione....come sempre!!!!!


  7. #7
    Utente di HTML.it L'avatar di Cool81
    Registrato dal
    Dec 2008
    Messaggi
    160
    Ho risolto così quell'eccezione:

    ho sostituito nel metodo per decriptare queste due righe:
    codice:
    byte[] newdata_psw = password_criptata.getBytes();
    byte[] dataPsw_decriptata = des.doFinal(newdata_psw);
    con questa

    codice:
    byte[] dataPsw_decriptata = des.doFinal(password_criptata.getBytes());
    Il problema è che ora la decriptazione non funziona bene, cioè non funziona proprio!!!

    Come si fa?????????????????????


  8. #8
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,315
    Tagliamo la testa al toro.
    Qualche anno fa un utente aveva postato questa classe: funziona bene.

    codice:
    import javax.crypto.*;
    import javax.crypto.spec.*;
    import java.io.*;
    
    public class DesEncrypter {
       Cipher ecipher;
       Cipher dcipher;
    
       // 8-byte Salt
       byte[] salt = {(byte)0xA9, (byte)0x9B, (byte)0xC8, (byte)0x32,
                      (byte)0x56, (byte)0x35, (byte)0xE3, (byte)0x03
                     };
    
       // Iteration count
       int iterationCount = 19;
    
       public DesEncrypter(String passPhrase) {
          try {
             // Create the key
             PBEKeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
             SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
             ecipher = Cipher.getInstance(key.getAlgorithm());
             dcipher = Cipher.getInstance(key.getAlgorithm());
    
             // Prepare the parameter to the ciphers
             PBEParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
    
             // Create the ciphers
             ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
             dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
          } catch (Exception e) { e.printStackTrace(); }
       }
    
       public String encrypt(String str) {
          String ret = null;
          try {
             // Encode the string into bytes using utf-8
             byte[] utf8 = str.getBytes("UTF8");
    
             // Encrypt
             byte[] enc = ecipher.doFinal(utf8);
    
             // Encode bytes to base64 to get a string
             ret = new sun.misc.BASE64Encoder().encode(enc);
          } catch (Exception e) { e.printStackTrace(); } 
          return ret;
      }
    
      public String decrypt(String str) {
         String ret = null;
         try {
            // Decode base64 to get bytes
            byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
    
            // Decrypt
            byte[] utf8 = dcipher.doFinal(dec);
    
            // Decode using utf-8
            ret = new String(utf8, "UTF8");
         } catch (Exception e) { e.printStackTrace(); }
         return ret;
       }
    }
    Esempio d'uso:

    codice:
    public class Prova {
       public static void main(String[] args) throws Exception {
          String tuaPassword = "pincopallino";
          DesEncrypter enc = new DesEncrypter("tua chiave");
          String criptata = enc.encrypt(tuaPassword);
          System.out.println("Password criptata: " + criptata);
          System.out.println("Password decriptata: " + enc.decrypt(criptata));
       }
    }
    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

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.