logo

¿Cómo cifrar la contraseña en Java?

Cada aplicación de software requiere un nombre de usuario y una contraseña para autenticar al usuario válido. Un nombre de usuario puede ser algo así como una identificación de correo electrónico o simplemente una combinación de caracteres. Pero al crear una contraseña hay que tener mucho cuidado. Porque cualquier persona con credenciales válidas puede ingresar al sistema y acceder a la información.

Necesidad de cifrar una contraseña

Cuando un usuario establece su contraseña, se almacena en la base de datos como texto sin formato. Almacenar el texto sin formato tal como está en la base de datos no es nada seguro. Los piratas informáticos pueden dañar el sistema y robar las contraseñas de la base de datos.

Para garantizar la seguridad de la contraseña del usuario, ésta se cifra mediante diferentes técnicas de cifrado. Utilizando diversas técnicas de cifrado, la contraseña de texto sin formato se almacena de forma cifrada en la base de datos. Existen muchos métodos que se pueden utilizar para cifrar la contraseña. Pero el hash es una de las técnicas de cifrado más populares.

Técnicas de hash seguro de Java

El valor hash cifrado se genera utilizando ciertos algoritmos en la contraseña de texto sin formato proporcionada por el usuario. La programación Java admite varias técnicas de hash para cifrar una contraseña.

Técnica de hash MD5

El MD5 (Message Digest) es un algoritmo hash muy popular. Es una función hash criptográfica que genera un valor hash de 128 bits. Este algoritmo se define en el paquete java.security en la programación Java.

PassEncTech1.java

 import java.security.NoSuchAlgorithmException; import java.security.MessageDigest; public class PassEncTech1 { /* Driver Code */ public static void main(String[] args) { /* Plain-text password initialization. */ String password = &apos;myPassword&apos;; String encryptedpassword = null; try { /* MessageDigest instance for MD5. */ MessageDigest m = MessageDigest.getInstance(&apos;MD5&apos;); /* Add plain-text password bytes to digest using MD5 update() method. */ m.update(password.getBytes()); /* Convert the hash value into bytes */ byte[] bytes = m.digest(); /* The bytes array has bytes in decimal form. Converting it into hexadecimal format. */ StringBuilder s = new StringBuilder(); for(int i=0; i <bytes.length ;i++) { s.append(integer.tostring((bytes[i] & 0xff) + 0x100, 16).substring(1)); } * complete hashed password in hexadecimal format encryptedpassword="s.toString();" catch (nosuchalgorithmexception e) e.printstacktrace(); display the unencrypted and encrypted passwords. system.out.println('plain-text password: ' password); system.out.println('encrypted using md5: encryptedpassword); < pre> <p> <strong>Output:</strong> </p> <pre> Plain-text password: myPassword Encrypted password using MD5: deb1536f480475f7d593219aa1afd74c </pre> <p>The above code shows the implementation of <strong> <em>MessageDigest</em> </strong> class in <strong> <em>java.security</em> </strong> package. The MD5 returns a byte array that needs to be converted into a readable hexadecimal format.</p> <p>The MD5 hashing technique is easy and fast to implement but it is also prone to brute force attacks or dictionary attacks.</p> <h3>SHA256</h3> <p>SHA is the Secure Hash Algorithm. It uses a cryptographic function that takes up the 32-bit plain-text password and converts it into a fixed size 256-bit hash value. This hashing technique is implemented using the MessageDiagest class of java.security package.</p> <p>It is a one-way encryption technique. Once the passphrase is encrypted it cannot be decrypted back.</p> <p> <strong>PassEncTech2.java</strong> </p> <pre> import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class PassEncTech2 { public static byte[] getSHA(String input) throws NoSuchAlgorithmException { /* MessageDigest instance for hashing using SHA256 */ MessageDigest md = MessageDigest.getInstance(&apos;SHA-256&apos;); /* digest() method called to calculate message digest of an input and return array of byte */ return md.digest(input.getBytes(StandardCharsets.UTF_8)); } public static String toHexString(byte[] hash) { /* Convert byte array of hash into digest */ BigInteger number = new BigInteger(1, hash); /* Convert the digest into hex value */ StringBuilder hexString = new StringBuilder(number.toString(16)); /* Pad with leading zeros */ while (hexString.length() <32) { hexstring.insert(0, '0'); } return hexstring.tostring(); * driver code public static void main(string args[]) try string string1="myPassword" ; system.out.println('
' + ' : tohexstring(getsha(string1))); string2="hashtrial" tohexstring(getsha(string2))); catch (nosuchalgorithmexception e) system.out.println('exception thrown for incorrect algorithm: e); < pre> <p> <strong>Output:</strong> </p> <pre> myPassword : 76549b827ec46e705fd03831813fa52172338f0dfcbd711ed44b81a96dac51c6 hashtrial : d3e3224a59d69e9a000f1ce6782cb6a8be1eb3155610ff41bffbcbc95adc5d7 </pre> <p>The above code uses the instance of <strong> <em>MessageDigest</em> </strong> class to generate a hash for <strong> <em>SHA256</em> </strong> . The SHA256 returns a byte array that needs to be converted into a readable hexadecimal format. And lastly, the encrypted hash value is displayed.</p> <h3>SHA512 MD5 Hashing Technique</h3> <p>SHA512 uses a cryptographic function that takes up the 64-bit plain-text password and converts it into a fixed size 512-bit hash value. This hashing technique is also implemented using the MessageDiagest class of java.security package.</p> <p> <strong>PassEncTech2.java</strong> </p> <pre> import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class PassEncTech2 { public static byte[] getSHA(String input) throws NoSuchAlgorithmException { /* MessageDigest instance for hashing using SHA512*/ MessageDigest md = MessageDigest.getInstance(&apos;SHA-512&apos;); /* digest() method called to calculate message digest of an input and return array of byte */ return md.digest(input.getBytes(StandardCharsets.UTF_8)); } public static String toHexString(byte[] hash) { /* Convert byte array of hash into digest */ BigInteger number = new BigInteger(1, hash); /* Convert the digest into hex value */ StringBuilder hexString = new StringBuilder(number.toString(16)); /* Pad with leading zeros */ while (hexString.length() <32) { hexstring.insert(0, '0'); } return hexstring.tostring(); * driver code public static void main(string args[]) try string string1="myPassword" ; system.out.println('
' + ' : tohexstring(getsha(string1))); string2="hashtrial" tohexstring(getsha(string2))); catch (nosuchalgorithmexception e) system.out.println('exception thrown for incorrect algorithm: e); < pre> <p> <strong>Output:</strong> </p> <pre> myPassword : 450ad03db9395dfccb5e03066fd7f16cfba2b61e23d516373714471459052ec90a9a4bf3a151e600ea8aaed36e3b8c21a3d38ab1705839749d130da4380f1448 hashtrial : 9520ea1a8d60d23334e6d59acebd587de6fec1e53db5836f467096c540ae60f7c85e9fbc90856dee9d6563609b8786b03b47892af0bad44bdcab2206f22df5cb </pre> <p>The above code uses the instance of <strong> <em>MessageDigest</em> </strong> class to generate a hash for <strong> <em>SHA512</em> </strong> . The SHA512 returns a byte array that needs to be converted into a readable hexadecimal format. And lastly, the encrypted hash value is displayed.</p> <h3>Password-Based Encryption using Salt and Base64:</h3> <p>The password-based encryption technique uses plain text passwords and salt values to generate a hash value. And the hash value is then encoded as a Base64 string. Salt value contains random data generated using an instance of Random class from java.util package.</p> <p>The following program demonstrates password encryption using salt and base64.</p> <p> <strong>PassEncTech4.java</strong> </p> <pre> import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.util.Arrays; import java.util.Base64; import java.util.Random; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; public class PassEncTech4 { /* Driver Code */ public static void main(String[] args) { /* Plain text Password. */ String password = &apos;myNewPass123&apos;; /* generates the Salt value. It can be stored in a database. */ String saltvalue = PassBasedEnc.getSaltvalue(30); /* generates an encrypted password. It can be stored in a database.*/ String encryptedpassword = PassBasedEnc.generateSecurePassword(password, saltvalue); /* Print out plain text password, encrypted password and salt value. */ System.out.println(&apos;Plain text password = &apos; + password); System.out.println(&apos;Secure password = &apos; + encryptedpassword); System.out.println(&apos;Salt value = &apos; + saltvalue); /* verify the original password and encrypted password */ Boolean status = PassBasedEnc.verifyUserPassword(password,encryptedpassword,saltvalue); if(status==true) System.out.println(&apos;Password Matched!!&apos;); else System.out.println(&apos;Password Mismatched&apos;); } } class PassBasedEnc { /* Declaration of variables */ private static final Random random = new SecureRandom(); private static final String characters = &apos;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&apos;; private static final int iterations = 10000; private static final int keylength = 256; /* Method to generate the salt value. */ public static String getSaltvalue(int length) { StringBuilder finalval = new StringBuilder(length); for (int i = 0; i <length; i++) { finalval.append(characters.charat(random.nextint(characters.length()))); } return new string(finalval); * method to generate the hash value public static byte[] hash(char[] password, salt) pbekeyspec spec="new" pbekeyspec(password, salt, iterations, keylength); arrays.fill(password, character.min_value); try secretkeyfactory skf="SecretKeyFactory.getInstance(&apos;PBKDF2WithHmacSHA1&apos;);" skf.generatesecret(spec).getencoded(); catch (nosuchalgorithmexception | invalidkeyspecexception e) throw assertionerror('error while hashing a password: ' + e.getmessage(), e); finally spec.clearpassword(); encrypt password using original and salt value. string generatesecurepassword(string finalval="null;" securepassword="hash(password.toCharArray()," salt.getbytes()); finalval; verify if both matches or not boolean verifyuserpassword(string providedpassword, securedpassword, secure with same newsecurepassword="generateSecurePassword(providedPassword," salt); check two passwords are equal < pre> <p> <strong>Output:</strong> </p> <pre> Plain text password = myNewPass123 Secure password = sA0jNGQTrAfMUiqrB++bMKTU55ThdFCl16ZZTIXwD2M= Salt value = n7d9MPQFXxDqzT6onmong3hQt8Nyko Password Matched!! </pre> <p>In the above code, two classes are defined.</p> <ol class="points"> <li>The class <strong> <em>PassEncTech4</em> </strong> contains the driver code for the program. It generates a salt value and encrypted password using the given plain-text password. And verifies them using the value returned by the <strong> <em>verifyUserPassword() </em> </strong> </li> <li>In the class <strong> <em>PassBasedEnc, </em> </strong> 4 methods are defined. The first method is <strong> <em>getSaltvalue()</em> </strong> which generates the value using <strong> <em>Random</em> </strong> class from <strong> <em>util</em> </strong> package. Then <strong> <em>hash()</em> </strong> is defined that has a return type of byte array. The <strong> <em>generateSecurePassword() </em> </strong> uses plain-text password and salt value with the <strong> <em>hash()</em> </strong> method. And lastly, the two passwords are matched using the <strong> <em>verifyUserPassword()</em> </strong> method.</li> </ol> <h2>Techniques for Cracking the Hash</h2> <p>A hash value is prone to different kinds of attacks by attackers. Some of them are mentioned below,</p> <ol class="points"> <tr><td>Brute force attack:</td> In the brute force attack, the attacker submits multiple combinations of passphrases or passwords in the hope that one of the combinations will match and he can enter into the system. <br> To avoid this kind of attack the passphrase should use a combination of alphabets, numbers and symbols. Another way is to set a fixed number of invalid attempts and after that ask for human verification like a captcha. </tr><tr><td>Dictionary attack:</td> Dictionary attack is an enhanced version of brute force attack. In this technique, the encrypted cipher is tried to be decrypted using multiple possibilities, like the words in a dictionary. </tr><tr><td>Rainbow tables:</td> The technique is about a rainbow table that is precomputed table for reversing the cryptographic hash functions. The rainbow tables are used to discover the plain text passwords up to a certain length and a limited number of characters. So it uses a side-loop table in order to reduce the storage usage and increase the speed of attack. </tr></ol> <hr></length;></pre></32)></pre></32)></pre></bytes.length>

El código anterior muestra la implementación de Resumen del mensaje clase en java.security paquete. El MD5 devuelve una matriz de bytes que debe convertirse a un formato hexadecimal legible.

La técnica de hash MD5 es fácil y rápida de implementar, pero también es propensa a ataques de fuerza bruta o de diccionario.

SHA256

SHA es el algoritmo Hash seguro. Utiliza una función criptográfica que toma la contraseña de texto sin formato de 32 bits y la convierte en un valor hash de 256 bits de tamaño fijo. Esta técnica de hash se implementa utilizando la clase MessageDigest del paquete java.security.

Es una técnica de cifrado unidireccional. Una vez cifrada la frase de contraseña, no se puede volver a descifrar.

PassEncTech2.java

 import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class PassEncTech2 { public static byte[] getSHA(String input) throws NoSuchAlgorithmException { /* MessageDigest instance for hashing using SHA256 */ MessageDigest md = MessageDigest.getInstance(&apos;SHA-256&apos;); /* digest() method called to calculate message digest of an input and return array of byte */ return md.digest(input.getBytes(StandardCharsets.UTF_8)); } public static String toHexString(byte[] hash) { /* Convert byte array of hash into digest */ BigInteger number = new BigInteger(1, hash); /* Convert the digest into hex value */ StringBuilder hexString = new StringBuilder(number.toString(16)); /* Pad with leading zeros */ while (hexString.length() <32) { hexstring.insert(0, \'0\'); } return hexstring.tostring(); * driver code public static void main(string args[]) try string string1="myPassword" ; system.out.println(\'
\' + \' : tohexstring(getsha(string1))); string2="hashtrial" tohexstring(getsha(string2))); catch (nosuchalgorithmexception e) system.out.println(\'exception thrown for incorrect algorithm: e); < pre> <p> <strong>Output:</strong> </p> <pre> myPassword : 76549b827ec46e705fd03831813fa52172338f0dfcbd711ed44b81a96dac51c6 hashtrial : d3e3224a59d69e9a000f1ce6782cb6a8be1eb3155610ff41bffbcbc95adc5d7 </pre> <p>The above code uses the instance of <strong> <em>MessageDigest</em> </strong> class to generate a hash for <strong> <em>SHA256</em> </strong> . The SHA256 returns a byte array that needs to be converted into a readable hexadecimal format. And lastly, the encrypted hash value is displayed.</p> <h3>SHA512 MD5 Hashing Technique</h3> <p>SHA512 uses a cryptographic function that takes up the 64-bit plain-text password and converts it into a fixed size 512-bit hash value. This hashing technique is also implemented using the MessageDiagest class of java.security package.</p> <p> <strong>PassEncTech2.java</strong> </p> <pre> import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class PassEncTech2 { public static byte[] getSHA(String input) throws NoSuchAlgorithmException { /* MessageDigest instance for hashing using SHA512*/ MessageDigest md = MessageDigest.getInstance(&apos;SHA-512&apos;); /* digest() method called to calculate message digest of an input and return array of byte */ return md.digest(input.getBytes(StandardCharsets.UTF_8)); } public static String toHexString(byte[] hash) { /* Convert byte array of hash into digest */ BigInteger number = new BigInteger(1, hash); /* Convert the digest into hex value */ StringBuilder hexString = new StringBuilder(number.toString(16)); /* Pad with leading zeros */ while (hexString.length() <32) { hexstring.insert(0, \'0\'); } return hexstring.tostring(); * driver code public static void main(string args[]) try string string1="myPassword" ; system.out.println(\'
\' + \' : tohexstring(getsha(string1))); string2="hashtrial" tohexstring(getsha(string2))); catch (nosuchalgorithmexception e) system.out.println(\'exception thrown for incorrect algorithm: e); < pre> <p> <strong>Output:</strong> </p> <pre> myPassword : 450ad03db9395dfccb5e03066fd7f16cfba2b61e23d516373714471459052ec90a9a4bf3a151e600ea8aaed36e3b8c21a3d38ab1705839749d130da4380f1448 hashtrial : 9520ea1a8d60d23334e6d59acebd587de6fec1e53db5836f467096c540ae60f7c85e9fbc90856dee9d6563609b8786b03b47892af0bad44bdcab2206f22df5cb </pre> <p>The above code uses the instance of <strong> <em>MessageDigest</em> </strong> class to generate a hash for <strong> <em>SHA512</em> </strong> . The SHA512 returns a byte array that needs to be converted into a readable hexadecimal format. And lastly, the encrypted hash value is displayed.</p> <h3>Password-Based Encryption using Salt and Base64:</h3> <p>The password-based encryption technique uses plain text passwords and salt values to generate a hash value. And the hash value is then encoded as a Base64 string. Salt value contains random data generated using an instance of Random class from java.util package.</p> <p>The following program demonstrates password encryption using salt and base64.</p> <p> <strong>PassEncTech4.java</strong> </p> <pre> import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.util.Arrays; import java.util.Base64; import java.util.Random; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; public class PassEncTech4 { /* Driver Code */ public static void main(String[] args) { /* Plain text Password. */ String password = &apos;myNewPass123&apos;; /* generates the Salt value. It can be stored in a database. */ String saltvalue = PassBasedEnc.getSaltvalue(30); /* generates an encrypted password. It can be stored in a database.*/ String encryptedpassword = PassBasedEnc.generateSecurePassword(password, saltvalue); /* Print out plain text password, encrypted password and salt value. */ System.out.println(&apos;Plain text password = &apos; + password); System.out.println(&apos;Secure password = &apos; + encryptedpassword); System.out.println(&apos;Salt value = &apos; + saltvalue); /* verify the original password and encrypted password */ Boolean status = PassBasedEnc.verifyUserPassword(password,encryptedpassword,saltvalue); if(status==true) System.out.println(&apos;Password Matched!!&apos;); else System.out.println(&apos;Password Mismatched&apos;); } } class PassBasedEnc { /* Declaration of variables */ private static final Random random = new SecureRandom(); private static final String characters = &apos;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&apos;; private static final int iterations = 10000; private static final int keylength = 256; /* Method to generate the salt value. */ public static String getSaltvalue(int length) { StringBuilder finalval = new StringBuilder(length); for (int i = 0; i <length; i++) { finalval.append(characters.charat(random.nextint(characters.length()))); } return new string(finalval); * method to generate the hash value public static byte[] hash(char[] password, salt) pbekeyspec spec="new" pbekeyspec(password, salt, iterations, keylength); arrays.fill(password, character.min_value); try secretkeyfactory skf="SecretKeyFactory.getInstance(&apos;PBKDF2WithHmacSHA1&apos;);" skf.generatesecret(spec).getencoded(); catch (nosuchalgorithmexception | invalidkeyspecexception e) throw assertionerror(\'error while hashing a password: \' + e.getmessage(), e); finally spec.clearpassword(); encrypt password using original and salt value. string generatesecurepassword(string finalval="null;" securepassword="hash(password.toCharArray()," salt.getbytes()); finalval; verify if both matches or not boolean verifyuserpassword(string providedpassword, securedpassword, secure with same newsecurepassword="generateSecurePassword(providedPassword," salt); check two passwords are equal < pre> <p> <strong>Output:</strong> </p> <pre> Plain text password = myNewPass123 Secure password = sA0jNGQTrAfMUiqrB++bMKTU55ThdFCl16ZZTIXwD2M= Salt value = n7d9MPQFXxDqzT6onmong3hQt8Nyko Password Matched!! </pre> <p>In the above code, two classes are defined.</p> <ol class="points"> <li>The class <strong> <em>PassEncTech4</em> </strong> contains the driver code for the program. It generates a salt value and encrypted password using the given plain-text password. And verifies them using the value returned by the <strong> <em>verifyUserPassword() </em> </strong> </li> <li>In the class <strong> <em>PassBasedEnc, </em> </strong> 4 methods are defined. The first method is <strong> <em>getSaltvalue()</em> </strong> which generates the value using <strong> <em>Random</em> </strong> class from <strong> <em>util</em> </strong> package. Then <strong> <em>hash()</em> </strong> is defined that has a return type of byte array. The <strong> <em>generateSecurePassword() </em> </strong> uses plain-text password and salt value with the <strong> <em>hash()</em> </strong> method. And lastly, the two passwords are matched using the <strong> <em>verifyUserPassword()</em> </strong> method.</li> </ol> <h2>Techniques for Cracking the Hash</h2> <p>A hash value is prone to different kinds of attacks by attackers. Some of them are mentioned below,</p> <ol class="points"> <tr><td>Brute force attack:</td> In the brute force attack, the attacker submits multiple combinations of passphrases or passwords in the hope that one of the combinations will match and he can enter into the system. <br> To avoid this kind of attack the passphrase should use a combination of alphabets, numbers and symbols. Another way is to set a fixed number of invalid attempts and after that ask for human verification like a captcha. </tr><tr><td>Dictionary attack:</td> Dictionary attack is an enhanced version of brute force attack. In this technique, the encrypted cipher is tried to be decrypted using multiple possibilities, like the words in a dictionary. </tr><tr><td>Rainbow tables:</td> The technique is about a rainbow table that is precomputed table for reversing the cryptographic hash functions. The rainbow tables are used to discover the plain text passwords up to a certain length and a limited number of characters. So it uses a side-loop table in order to reduce the storage usage and increase the speed of attack. </tr></ol> <hr></length;></pre></32)></pre></32)>

El código anterior utiliza la instancia de Resumen del mensaje clase para generar un hash para SHA256 . El SHA256 devuelve una matriz de bytes que debe convertirse a un formato hexadecimal legible. Y por último, se muestra el valor hash cifrado.

Técnica de hash SHA512 MD5

SHA512 utiliza una función criptográfica que toma la contraseña de texto sin formato de 64 bits y la convierte en un valor hash de 512 bits de tamaño fijo. Esta técnica de hash también se implementa utilizando la clase MessageDigest del paquete java.security.

PassEncTech2.java

 import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class PassEncTech2 { public static byte[] getSHA(String input) throws NoSuchAlgorithmException { /* MessageDigest instance for hashing using SHA512*/ MessageDigest md = MessageDigest.getInstance(&apos;SHA-512&apos;); /* digest() method called to calculate message digest of an input and return array of byte */ return md.digest(input.getBytes(StandardCharsets.UTF_8)); } public static String toHexString(byte[] hash) { /* Convert byte array of hash into digest */ BigInteger number = new BigInteger(1, hash); /* Convert the digest into hex value */ StringBuilder hexString = new StringBuilder(number.toString(16)); /* Pad with leading zeros */ while (hexString.length() <32) { hexstring.insert(0, \'0\'); } return hexstring.tostring(); * driver code public static void main(string args[]) try string string1="myPassword" ; system.out.println(\'
\' + \' : tohexstring(getsha(string1))); string2="hashtrial" tohexstring(getsha(string2))); catch (nosuchalgorithmexception e) system.out.println(\'exception thrown for incorrect algorithm: e); < pre> <p> <strong>Output:</strong> </p> <pre> myPassword : 450ad03db9395dfccb5e03066fd7f16cfba2b61e23d516373714471459052ec90a9a4bf3a151e600ea8aaed36e3b8c21a3d38ab1705839749d130da4380f1448 hashtrial : 9520ea1a8d60d23334e6d59acebd587de6fec1e53db5836f467096c540ae60f7c85e9fbc90856dee9d6563609b8786b03b47892af0bad44bdcab2206f22df5cb </pre> <p>The above code uses the instance of <strong> <em>MessageDigest</em> </strong> class to generate a hash for <strong> <em>SHA512</em> </strong> . The SHA512 returns a byte array that needs to be converted into a readable hexadecimal format. And lastly, the encrypted hash value is displayed.</p> <h3>Password-Based Encryption using Salt and Base64:</h3> <p>The password-based encryption technique uses plain text passwords and salt values to generate a hash value. And the hash value is then encoded as a Base64 string. Salt value contains random data generated using an instance of Random class from java.util package.</p> <p>The following program demonstrates password encryption using salt and base64.</p> <p> <strong>PassEncTech4.java</strong> </p> <pre> import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.util.Arrays; import java.util.Base64; import java.util.Random; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; public class PassEncTech4 { /* Driver Code */ public static void main(String[] args) { /* Plain text Password. */ String password = &apos;myNewPass123&apos;; /* generates the Salt value. It can be stored in a database. */ String saltvalue = PassBasedEnc.getSaltvalue(30); /* generates an encrypted password. It can be stored in a database.*/ String encryptedpassword = PassBasedEnc.generateSecurePassword(password, saltvalue); /* Print out plain text password, encrypted password and salt value. */ System.out.println(&apos;Plain text password = &apos; + password); System.out.println(&apos;Secure password = &apos; + encryptedpassword); System.out.println(&apos;Salt value = &apos; + saltvalue); /* verify the original password and encrypted password */ Boolean status = PassBasedEnc.verifyUserPassword(password,encryptedpassword,saltvalue); if(status==true) System.out.println(&apos;Password Matched!!&apos;); else System.out.println(&apos;Password Mismatched&apos;); } } class PassBasedEnc { /* Declaration of variables */ private static final Random random = new SecureRandom(); private static final String characters = &apos;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&apos;; private static final int iterations = 10000; private static final int keylength = 256; /* Method to generate the salt value. */ public static String getSaltvalue(int length) { StringBuilder finalval = new StringBuilder(length); for (int i = 0; i <length; i++) { finalval.append(characters.charat(random.nextint(characters.length()))); } return new string(finalval); * method to generate the hash value public static byte[] hash(char[] password, salt) pbekeyspec spec="new" pbekeyspec(password, salt, iterations, keylength); arrays.fill(password, character.min_value); try secretkeyfactory skf="SecretKeyFactory.getInstance(&apos;PBKDF2WithHmacSHA1&apos;);" skf.generatesecret(spec).getencoded(); catch (nosuchalgorithmexception | invalidkeyspecexception e) throw assertionerror(\'error while hashing a password: \' + e.getmessage(), e); finally spec.clearpassword(); encrypt password using original and salt value. string generatesecurepassword(string finalval="null;" securepassword="hash(password.toCharArray()," salt.getbytes()); finalval; verify if both matches or not boolean verifyuserpassword(string providedpassword, securedpassword, secure with same newsecurepassword="generateSecurePassword(providedPassword," salt); check two passwords are equal < pre> <p> <strong>Output:</strong> </p> <pre> Plain text password = myNewPass123 Secure password = sA0jNGQTrAfMUiqrB++bMKTU55ThdFCl16ZZTIXwD2M= Salt value = n7d9MPQFXxDqzT6onmong3hQt8Nyko Password Matched!! </pre> <p>In the above code, two classes are defined.</p> <ol class="points"> <li>The class <strong> <em>PassEncTech4</em> </strong> contains the driver code for the program. It generates a salt value and encrypted password using the given plain-text password. And verifies them using the value returned by the <strong> <em>verifyUserPassword() </em> </strong> </li> <li>In the class <strong> <em>PassBasedEnc, </em> </strong> 4 methods are defined. The first method is <strong> <em>getSaltvalue()</em> </strong> which generates the value using <strong> <em>Random</em> </strong> class from <strong> <em>util</em> </strong> package. Then <strong> <em>hash()</em> </strong> is defined that has a return type of byte array. The <strong> <em>generateSecurePassword() </em> </strong> uses plain-text password and salt value with the <strong> <em>hash()</em> </strong> method. And lastly, the two passwords are matched using the <strong> <em>verifyUserPassword()</em> </strong> method.</li> </ol> <h2>Techniques for Cracking the Hash</h2> <p>A hash value is prone to different kinds of attacks by attackers. Some of them are mentioned below,</p> <ol class="points"> <tr><td>Brute force attack:</td> In the brute force attack, the attacker submits multiple combinations of passphrases or passwords in the hope that one of the combinations will match and he can enter into the system. <br> To avoid this kind of attack the passphrase should use a combination of alphabets, numbers and symbols. Another way is to set a fixed number of invalid attempts and after that ask for human verification like a captcha. </tr><tr><td>Dictionary attack:</td> Dictionary attack is an enhanced version of brute force attack. In this technique, the encrypted cipher is tried to be decrypted using multiple possibilities, like the words in a dictionary. </tr><tr><td>Rainbow tables:</td> The technique is about a rainbow table that is precomputed table for reversing the cryptographic hash functions. The rainbow tables are used to discover the plain text passwords up to a certain length and a limited number of characters. So it uses a side-loop table in order to reduce the storage usage and increase the speed of attack. </tr></ol> <hr></length;></pre></32)>

El código anterior utiliza la instancia de Resumen del mensaje clase para generar un hash para SHA512 . El SHA512 devuelve una matriz de bytes que debe convertirse a un formato hexadecimal legible. Y por último, se muestra el valor hash cifrado.

Cifrado basado en contraseña utilizando Salt y Base64:

La técnica de cifrado basada en contraseñas utiliza contraseñas de texto sin formato y valores salt para generar un valor hash. Y el valor hash luego se codifica como una cadena Base64. El valor Salt contiene datos aleatorios generados utilizando una instancia de la clase Random del paquete java.util.

El siguiente programa demuestra el cifrado de contraseñas utilizando salt y base64.

PassEncTech4.java

 import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.util.Arrays; import java.util.Base64; import java.util.Random; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; public class PassEncTech4 { /* Driver Code */ public static void main(String[] args) { /* Plain text Password. */ String password = &apos;myNewPass123&apos;; /* generates the Salt value. It can be stored in a database. */ String saltvalue = PassBasedEnc.getSaltvalue(30); /* generates an encrypted password. It can be stored in a database.*/ String encryptedpassword = PassBasedEnc.generateSecurePassword(password, saltvalue); /* Print out plain text password, encrypted password and salt value. */ System.out.println(&apos;Plain text password = &apos; + password); System.out.println(&apos;Secure password = &apos; + encryptedpassword); System.out.println(&apos;Salt value = &apos; + saltvalue); /* verify the original password and encrypted password */ Boolean status = PassBasedEnc.verifyUserPassword(password,encryptedpassword,saltvalue); if(status==true) System.out.println(&apos;Password Matched!!&apos;); else System.out.println(&apos;Password Mismatched&apos;); } } class PassBasedEnc { /* Declaration of variables */ private static final Random random = new SecureRandom(); private static final String characters = &apos;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&apos;; private static final int iterations = 10000; private static final int keylength = 256; /* Method to generate the salt value. */ public static String getSaltvalue(int length) { StringBuilder finalval = new StringBuilder(length); for (int i = 0; i <length; i++) { finalval.append(characters.charat(random.nextint(characters.length()))); } return new string(finalval); * method to generate the hash value public static byte[] hash(char[] password, salt) pbekeyspec spec="new" pbekeyspec(password, salt, iterations, keylength); arrays.fill(password, character.min_value); try secretkeyfactory skf="SecretKeyFactory.getInstance(&apos;PBKDF2WithHmacSHA1&apos;);" skf.generatesecret(spec).getencoded(); catch (nosuchalgorithmexception | invalidkeyspecexception e) throw assertionerror(\\'error while hashing a password: \\' + e.getmessage(), e); finally spec.clearpassword(); encrypt password using original and salt value. string generatesecurepassword(string finalval="null;" securepassword="hash(password.toCharArray()," salt.getbytes()); finalval; verify if both matches or not boolean verifyuserpassword(string providedpassword, securedpassword, secure with same newsecurepassword="generateSecurePassword(providedPassword," salt); check two passwords are equal < pre> <p> <strong>Output:</strong> </p> <pre> Plain text password = myNewPass123 Secure password = sA0jNGQTrAfMUiqrB++bMKTU55ThdFCl16ZZTIXwD2M= Salt value = n7d9MPQFXxDqzT6onmong3hQt8Nyko Password Matched!! </pre> <p>In the above code, two classes are defined.</p> <ol class="points"> <li>The class <strong> <em>PassEncTech4</em> </strong> contains the driver code for the program. It generates a salt value and encrypted password using the given plain-text password. And verifies them using the value returned by the <strong> <em>verifyUserPassword() </em> </strong> </li> <li>In the class <strong> <em>PassBasedEnc, </em> </strong> 4 methods are defined. The first method is <strong> <em>getSaltvalue()</em> </strong> which generates the value using <strong> <em>Random</em> </strong> class from <strong> <em>util</em> </strong> package. Then <strong> <em>hash()</em> </strong> is defined that has a return type of byte array. The <strong> <em>generateSecurePassword() </em> </strong> uses plain-text password and salt value with the <strong> <em>hash()</em> </strong> method. And lastly, the two passwords are matched using the <strong> <em>verifyUserPassword()</em> </strong> method.</li> </ol> <h2>Techniques for Cracking the Hash</h2> <p>A hash value is prone to different kinds of attacks by attackers. Some of them are mentioned below,</p> <ol class="points"> <tr><td>Brute force attack:</td> In the brute force attack, the attacker submits multiple combinations of passphrases or passwords in the hope that one of the combinations will match and he can enter into the system. <br> To avoid this kind of attack the passphrase should use a combination of alphabets, numbers and symbols. Another way is to set a fixed number of invalid attempts and after that ask for human verification like a captcha. </tr><tr><td>Dictionary attack:</td> Dictionary attack is an enhanced version of brute force attack. In this technique, the encrypted cipher is tried to be decrypted using multiple possibilities, like the words in a dictionary. </tr><tr><td>Rainbow tables:</td> The technique is about a rainbow table that is precomputed table for reversing the cryptographic hash functions. The rainbow tables are used to discover the plain text passwords up to a certain length and a limited number of characters. So it uses a side-loop table in order to reduce the storage usage and increase the speed of attack. </tr></ol> <hr></length;>

En el código anterior, se definen dos clases.

  1. La clase PaseEncTech4 contiene el código del controlador del programa. Genera un valor salt y una contraseña cifrada utilizando la contraseña de texto sin formato proporcionada. Y los verifica usando el valor devuelto por el verificarContraseñaUsuario()
  2. En la clase PassBasedEnc, Se definen 4 métodos. El primer método es obtenerValorSal() que genera el valor usando aleatorio clase de útil paquete. Entonces picadillo() se define que tiene un tipo de retorno de matriz de bytes. El generarContraseñaSegura() utiliza contraseña de texto sin formato y valor salt con el picadillo() método. Y por último, las dos contraseñas se hacen coincidir usando el verificarContraseñaUsuario() método.

Técnicas para descifrar el hachís

Un valor hash es propenso a diferentes tipos de ataques por parte de atacantes. Algunos de ellos se mencionan a continuación,

    Ataque de fuerza bruta:En el ataque de fuerza bruta, el atacante envía múltiples combinaciones de frases de contraseña o contraseñas con la esperanza de que una de las combinaciones coincida y pueda ingresar al sistema.
    Para evitar este tipo de ataques, la frase de contraseña debe utilizar una combinación de alfabetos, números y símbolos. Otra forma es establecer un número fijo de intentos no válidos y luego solicitar la verificación humana como un captcha.Ataque de diccionario:El ataque de diccionario es una versión mejorada del ataque de fuerza bruta. En esta técnica, se intenta descifrar el cifrado cifrado utilizando múltiples posibilidades, como las palabras de un diccionario.Mesas arcoiris:La técnica consiste en una tabla de arcoíris que es una tabla precalculada para invertir las funciones hash criptográficas. Las tablas de arco iris se utilizan para descubrir contraseñas de texto sin formato con una longitud determinada y un número limitado de caracteres. Por lo tanto, utiliza una tabla de bucle lateral para reducir el uso de almacenamiento y aumentar la velocidad de ataque.