Problemi in crittografia password

di il
5 risposte

Problemi in crittografia password

Sto facendo una web application di tipo monolitico in java con .jsp

nella pagina di registrazione utenti, nel controller, in fase di settaggio delle property dei campi che utilizzo nella form di registrazione, prima di eseguire il metodo che effettua la registrazione fisica del record nel database sql server, effettuo la criptazione della password.

l'operazione viene eseguita in maniera corretta

ecco il metodo che utilizzo

	@RequestMapping(value = "/aggiungi", method = RequestMethod.POST)
	public String GestInsAnadip(@Valid @ModelAttribute("userform") AnadipForm anadipForm, BindingResult result, Model model,
			RedirectAttributes redirectAttributes, HttpServletRequest request)
	{
		
		String functionUser = "Inserimento";
		
		if (result.hasErrors())
		{
			return "insAnadip";
		}
		
		// se non ho selezionato ne si e ne no in loggabile
		if(anadipForm.getLoggabile() == null) {
			return "insAnadip";
		}
		
		if (result.getSuppressedFields().length > 0)
			throw new RuntimeException("ERRORE: Tentativo di eseguire il binding dei seguenti campi NON consentiti: "
					+ StringUtils.arrayToCommaDelimitedString(result.getSuppressedFields()));
		else
		{
			Anadip anadip = new Anadip();
			// imposto i dati da AnadipForm
			
			anadip.setCognome(anadipForm.getCognome().toUpperCase());
			anadip.setKeyUserOp(9999);                                // inserire l'utente ceh ha effettuato la modifica - prenderlo da utente corrente
			anadip.setLoggabile(anadipForm.getLoggabile());
			anadip.setMatricola(anadipForm.getMatricola());
			anadip.setNome(anadipForm.getNome().toUpperCase());
			anadip.setNoteanag(anadipForm.getNoteanag());
			anadip.setUserid(anadipForm.getUserid().toUpperCase());
			anadip.setDateOp(date);
			
			//CRITTIAMO LA PASSWORD
			String encodedPassword = passwordEncoder.encode(anadipForm.getPassword());
			anadip.setPassword(encodedPassword); 
			
			// inserisco le relazioni verso le tabelle correlate
			
			T_Titolo ttit = new T_Titolo();
			
			ttit = t_titoloService.SelByIdTitolo(anadipForm.getTitolo());
			anadip.setTtitolo(ttit);
			
			UserLevels ulev = new UserLevels();
			ulev = userLevelsService.SelById(anadipForm.getUserlevel());
			anadip.setUserlevels(ulev);
			
			T_StatoUtente staut = new T_StatoUtente();
			staut = t_statoUtenteService.SelByIdStatoUtente(anadipForm.getIdStato());
			anadip.setTstatoutente(staut);
		
			anadipService.Salva(anadip);   
			
			redirectAttributes.addFlashAttribute("saved", true);
				
			 return "redirect:/anadip/successAnadip/"+ anadip.getMatricola() + "/" +  functionUser;     // visualizza messaggio di corretta operatività  - deve essere questo corrett
				
		}
	}


in fase di logon della web application, quando vado a impostare le credenziali dell'utente appena inserito, effettuo anche in questo caso la crittografia della password inserita nel form di login per effettuare una lettura delle credenziali e quindi verificare se utente registrato.

ecco il metodo che utilizzo nel controller


	@RequestMapping(method = RequestMethod.POST)
	public String getLoginPost(@ModelAttribute("userform") Anadip anadip,Model model,HttpServletRequest request, HttpServletResponse response)
	{
		// recupero i valori inseriti nel model
		
		Anadip record = null;
		if (anadip.getUserid() != null  && anadip.getPassword() != null) {
			
			//cripto LA PASSWORD
			
			String encodedPassword = passwordEncoder.encode(anadip.getPassword());    
			record = anadipService.SelByUsernamePassword(anadip.getUserid(), encodedPassword);    
							
			if(record == null)  {
				System.out.println("-------GetLoginPost -- eseguita lettura senza record --------  userid:  " + anadip.getUserid() + "  password : " + anadip.getPassword());	
			}
			else
			{
				System.out.println("-------GetLoginPost -- eseguita lettura -- record trovato --------  userid:  " + anadip.getUserid() + "  password : " + anadip.getPassword());	
				return "redirect:/";
			}
			
		}
		
		
		
		String[] test = request.getParameterValues("logout");
		
		if (test != null)
		{
			Cookie cookieWithSlash = new Cookie("JSESSIONID", null);
	        //Tomcat adds extra slash at the end of context path (e.g. "/foo/")
	        cookieWithSlash.setPath(request.getContextPath() + "/"); 
	        cookieWithSlash.setMaxAge(0); 

	        Cookie cookieWithoutSlash = new Cookie("JSESSIONID", null);
	        //JBoss doesn't add extra slash at the end of context path (e.g. "/foo")
	        cookieWithoutSlash.setPath(request.getContextPath()); 
	        cookieWithoutSlash.setMaxAge(0); 

	        //Remove cookies on logout so that invalidSessionURL (session timeout) is not displayed on proper logout event
	        response.addCookie(cookieWithSlash); //For cookie added by Tomcat 
	        response.addCookie(cookieWithoutSlash); //For cookie added by JBoss
	        
	        if (test.length == 2)
	        {
	        	 logger.info("utente: " + test[1]); 
				 persistentTokenRepository.removeUserTokens(test[1]);
	        }
	        
		}
		
		return "redirect:/login/form?logout";
	}



quindi sia in fase di registrazione dell'utente che in fase di lettura delle credenziali d'accesso, sul campo password inserito dall'utente effettuo la crittografia utilizzando il metodo passwordEncoder.encode

String encodedPassword = passwordEncoder.encode(anadip.getPassword());   
Ho verificato che lo stesso campo, eseguendo la criptazione più volte, crea dei valori criptati diversi ad ogni operazione.

in questo esempio effettuo per la password "paperino" scritta in minuscolo valori del tutto diversi


$2a$10$RkdWTFJ8F4ZnzFCT/cFjBOeneVY.1C1FZ1yeuVevFXySGsgoQ7Ywm   paperino minuscolo
$2a$10$jAxq8ekwRB5m.e0InPHLEOPLQA5rWEV3ROPCgm3ET2YUbjp2bF./a   paperino maiuscolo

$2a$10$3SUW8RfUbrD67am2Z6st7.n7zZI0DdsEGGhPoLS/05It5tISBgsuS	paperino minuscolo

Non capisco perchè e come posso risolvere il problema.
Rimango a disposizione se non sono riuscito a spiegare in mnaiera chiara il problema.

Grazie

Moreno

5 Risposte

  • Re: Problemi in crittografia password

    misonsan ha scritto:


    eseguendo la criptazione più volte, crea dei valori criptati diversi ad ogni operazione.
    Il Bcrypt funziona così.

    misonsan ha scritto:


    Non capisco perchè e come posso risolvere il problema.
    La questione è che non sei tu che puoi confrontare due hash (non avresti mai il risultato voluto). Ma è l'algoritmo del Bcrypt che lo può (e "sa") fare. Dato che hai (sicuramente) usato Spring Security, avrai visto che PasswordEncoder ha encode() e il matches() . Quest'ultimo è quello che va usato per l'autenticazione.
  • Re: Problemi in crittografia password

    Ciao AndBin

    Grazie per la cortese risposta.

    nella tua risposta hai detto
    La questione è che non sei tu che puoi confrontare due hash (non avresti mai il risultato voluto). Ma è l'algoritmo del Bcrypt che lo può (e "sa") fare. Dato che hai (sicuramente) usato Spring Security, avrai visto che PasswordEncoder ha encode() e il matches() . Quest'ultimo è quello che va usato per l'autenticazione.
    Non capisco allora come potrei fare a fare una verifica della password utente se la crittografia cambia continuamente.
    Hai un esempio per casp ?

    Ho usato Spring Security.

    Grazie

    Moreno
  • Re: Problemi in crittografia password

    
    BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    String existingPassword = ... // Password entered by user
    String dbPassword       = ... // Load hashed DB password
    
    if (passwordEncoder.matches(existingPassword, dbPassword)) {
        // Encode new password and store it
    } else {
        // Report error 
    }
    
  • Re: Problemi in crittografia password

    misonsan ha scritto:


    Non capisco allora come potrei fare a fare una verifica della password utente se la crittografia cambia continuamente.
    Ma non ti interessa se cambia ad ogni encode. Perché il encode lo devi fare UNA volta sola.

    L'utente si registra, mette username "paperino" e password "pap3926". Tu usi il encode() del PasswordEncoder per ottenere da questa password il hash Bcrypt "$2a$......." e lo memorizzi nel record utente su DB.

    Poi l'utente si logga tutte le volte che vuole. Tu ricevi ogni volta "paperino"/"pap3926", vai su DB a cercare il record per "paperino" e prendi il hash Bcrypt. Questo hash lo passi al matches() del PasswordEncoder, primo argomento la password in chiaro ("pap3926") e come secondo argomento, il hash preso da DB. Se il matches ti dà true, l'utente è autenticato.

    Al suo interno, il PasswordEncoder del Bcrypt farà sicuramente un hash di nuovo della password in chiaro (è un hash .. non una cosa decifrabile all'indietro!) ed avrà sì un hash differente. Ma è il Bcrypt che SA come confrontare due hash differenti, il modo lui ce l'ha!! NON lo devi sapere tu.
  • Re: Problemi in crittografia password

    Grazie a AndBin e a gian82 per il prezioso aiuto.
    Funziona regolarmente e l'utente è verificto con la password.

    grazie

    Moreno
Devi accedere o registrarti per scrivere nel forum
5 risposte