Codifica sicura della password con SHA256

DOMANDA:

Come posso creare un sistema di conservazione sicura delle password nel database della mia applicazione?



RISPOSTA:

Il metodo più usato per conservare in maniera sicura le password consiste nel "cifrarle" con alcuni algoritmi che utilizzano funzioni non invertibili (one-way).

Nell'esempio vi mostrerò come cifrare utilizzando SHA256, attualmente un buon compromesso tra sicurezza e costi computazionali per un'applicazione media. In ogni caso vedremo quanto è facile modificare il tipo di cifratura utilizzata.


Di seguito la classe PwdCoder che effettua la codifica e il test della password:
package codificapassword; 

public class PwdCoder{
  public static String getEncodedPassword(String clearTextPassword)
                                     throws NoSuchAlgorithmException {

    MessageDigest md = MessageDigest.getInstance("SHA-256");
    md.update(clearTextPassword.getBytes());

    return HexString.bufferToHex(md.digest()); //md.digest() effettua il padding finale
  }

  public static boolean testPassword(String clearTextTestPassword, String encodedActualPassword) throws NoSuchAlgorithmException {

    String encodedTestPassword = 
                          getEncodedPassword(clearTextTestPassword);

    return (encodedTestPassword.equals(encodedActualPassword));
  }
}
Alcuni algoritmi di MessageDigest sono  MD5, CRC32,  SHA-1,  SHA-256,  SHA-384 e SHA-512.



La classe di appoggio HexString:

package codificapassword; 

public class HexString {

  static char[] hexChar = 
     {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

  static String bufferToHex(byte[] b) {
    StringBuffer sb = new StringBuffer( b.length * 2 );

    for (int i=0; i<b.length; i++) {
      sb.append(hexChar [( b[i] & 0xf0 ) >>> 4 ]) ;
      sb.append(hexChar [b[ i] & 0x0f]) ;
    }

    return sb.toString() ;
 } 
}

Infine la classe di test:

package codificapassword; 

import java.security.NoSuchAlgorithmException; 

public class TestCodifica { 
  public static void main(String args[]) throws NoSuchAlgorithmException { 

    System.out.println(PwdCoder.getEncodedPassword("ciaoPass")); 
  } 
}
L'output di TestCodifica:
E15B9D3B76D74F9ECCCD2377A19A8780D05CB6A8F4332B8DB269BC2027778FB0

Per aumentare la sicurezza delle password ed evitare che siano facilmente svelate con le Rainbow Tables, è buona norma concatenare un salt (meglio se randomico). Per ulteriori approfondimenti sull'hashing di password e sul salting potete consultare questa pagina.

Commenti

Post popolari in questo blog

Arrotondamento e troncamento in Java

Eclipse: Shortcuts (scorciatoie) da tastiera

Strutture dati: List, Set, Map

Creare un eseguibile Java