Criptografía
Uso de criptografía en Java
Encriptación:
Criptografía en Java
Arquitectura Criptográfica de Java (JCA)
Obtener la lista completa de los proveedores disponibles en tu sistema:
ObtenerListaProveedores.java
import java.security.Provider;
import java.security.Security;
public class ObtenerListaProveedores {
public static void main(String[] args) {
// Obtener todos los proveedores de seguridad
Provider[] providers = Security.getProviders();
for (Provider provider : providers) {
System.out.printf("Proveedor: %s\n", provider.getName());
}
}
}
Ejecición
javac ObtenerListaProveedores.java java ObtenerListaProveedores
Obtener la lista de servicios de esos proveedores:
ObtenerListaServicios.java
import java.security.Provider;
import java.security.Security;
import java.util.Set;
public class ObtenerListaServicios {
public static void main(String[] args) {
// Obtener todos los proveedores de seguridad
Provider[] providers = Security.getProviders();
for (Provider provider : providers) {
// Obtener los servicios de MessageDigest del proveedor
Set<Provider.Service> services = provider.getServices();
System.out.printf("Proveedor: %s\n", provider.getName());
System.out.printf("-----------%s\n", "-".repeat(provider.getName().length()));
for (Provider.Service service : services) {
// Obtener el servicio (algoritmo)
String algoritmo = service.getAlgorithm();
// Imprimir el algoritmo
System.out.printf("Servicio: %s - Tipo: %s\n",
algoritmo, service.getType());
}
System.out.println();
}
}
}
Obtener más información:
InfoProveedores.java
// InfoProveedores.java
import java.security.*;
import java.util.*;
class InfoProveedores {
public static void main(String[] args) {
boolean listarProps = false;
if ( args.length > 0 && args[0].equals("-l") )
listarProps=true;
System.out.println("------------------------------------");
System.out.println("Proveedores instalados en su sistema");
System.out.println("------------------------------------");
Provider[] listaProv = Security.getProviders();
for (int i = 0; i < listaProv.length; i++) {
System.out.println("Núm. proveedor : " + (i + 1));
System.out.println("Nombre : " + listaProv[i].getName());
System.out.println("Versión : " + listaProv[i].getVersion());
System.out.println("Información :\n " + listaProv[i].getInfo());
System.out.println("Propiedades :");
if (listarProps) {
Enumeration propiedades = listaProv[i].propertyNames();
while (propiedades.hasMoreElements()) {
String clave = (String) propiedades.nextElement();
String valor = listaProv[i].getProperty(clave);
System.out.println(" " + clave + " = " + valor);
}
}
System.out.println("------------------------------------");
}
}
}
Generación de una pareja de claves (pública y privada)
Claves.java
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
public class Claves {
//Programa que crea una pareja de claves (pública y privada) y las muestra
public static void main(String[] args) {
//Asigna al objeto claves de tipo keyPair el par de claves generadas
//por el método GeneraParejaClave()
System.out.println ("Generando pareja de claves pública-privada (PKI)\n");
KeyPair claves = null;
try {
//Crea el objeto para generar un par de claves mediante RSA
KeyPairGenerator genera = KeyPairGenerator.getInstance("RSA");
genera.initialize(512); //asigna tamaño de la clave
claves = genera.generateKeyPair(); //genera la pareja de claves
} catch (NoSuchAlgorithmException ex) {
System.out.printf ("Error: %s\n", ex.getMessage());
ex.printStackTrace();
}
//Imprime el valor de las claves generadas
if (claves != null) {
System.out.println ("Pareja de claves generada");
System.out.println ("-------------------------");
System.out.printf("Algoritmo Kprivada: %s\n\n", claves.getPrivate().getAlgorithm());
System.out.printf("Codificación Kprivada: %s\n\n", claves.getPrivate().getFormat());
System.out.printf("Bytes Kprivada: %s\n\n", claves.getPrivate().toString());
System.out.printf("Algoritmo Kpública: %s\n\n", claves.getPublic().getAlgorithm());
System.out.printf("Codificación Kpública: %s\n\n", claves.getPublic().getFormat());
System.out.printf("Bytes Kpública: %s\n\n", claves.getPublic().toString());
}
}
}
Resúmenes de mensajes (Hash)
Hash.java
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Hash {
public static void main(String[] args) {
String[] listaAlgoritmos = {"MD5", "SHA-1", "SHA-256", "SHA-384", "SHA-512"};
String texto = "Texto de ejemplo para generar resumen";
System.out.printf("Texto: %s\n", texto);
for (int i = 0; i < listaAlgoritmos.length; i++) {
try {
MessageDigest algoritmoHash = MessageDigest.getInstance(listaAlgoritmos[i]);
algoritmoHash.update(texto.getBytes()); //obtiene el resumen
byte[] resumen = algoritmoHash.digest(); //completa la generación del resumen
// Convertimos el array de bytes a una representación hexadecimal "legible" por humanos
StringBuilder sb = new StringBuilder();
for (byte b : resumen) {
sb.append(String.format("%02x", b));
}
// Mostramos el resumen por pantalla
System.out.printf("Resumen %s: %s\n", listaAlgoritmos[i], sb.toString());
} catch (NoSuchAlgorithmException ex) {
System.out.printf("Error: %s\n", ex.getMessage());
}
}
}
}
Ejemplos de encriptación simétrica y asímetrica con Cipher
Algoritmos de cifrado simétrico
CifradoDES.java
import java.security.*; //JCA
import javax.crypto.*; //JCE
import java.io.*; //ficheros
//Programa que encripta y desencripta un fichero
//mediante clave privada o simétrica utilizando el algoritmo DES
public class CifradoDES {
public static void main(String[] Args) {
//declara e incializa objeto tipo clave secreta
SecretKey clave = null;
//llama a los métodos que encripta/desencripta un fichero
try {
//Llama al método que encripta el fichero que se pasa como parámetro
clave = cifrarFichero("./fichero.txt");
//Llama la método que desencripta el fichero pasado como primer parámetro
descifrarFichero("./fichero.txt.cifrado", clave,
"./fichero.descifrado.txt");
} catch (Exception e) {
e.printStackTrace();
}
}
//método que encripta el fichero que se pasa como parámetro
//devuelve el valor de la clave privada utilizada en encriptación
//El fichero encriptado lo deja en el archivo de nombre fichero.cifrado
//en el mismo directorio
private static SecretKey cifrarFichero(String file) throws NoSuchAlgorithmException, NoSuchPaddingException, FileNotFoundException, IOException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException {
FileInputStream fe = null; //fichero de entrada
FileOutputStream fs = null; //fichero de salida
int bytesLeidos;
//1. Crear e inicializar clave
System.out.println("1.-Genera clave DES");
//crea un objeto para generar la clave usando algoritmo DES
KeyGenerator keyGen = KeyGenerator.getInstance("DES");
keyGen.init(56); //se indica el tamaño de la clave
SecretKey clave = keyGen.generateKey(); //genera la clave privada
System.out.println("Clave");
mostrarBytes(clave.getEncoded()); //muestra la clave
System.out.println();
//Se Crea el objeto Cipher para cifrar, utilizando el algoritmo DES
Cipher cifrador = Cipher.getInstance("DES");
//Se inicializa el cifrador en modo CIFRADO o ENCRIPTACIÓN
cifrador.init(Cipher.ENCRYPT_MODE, clave);
System.out.println("2.- Cifrar con DES el fichero: " + file + ", y dejar resultado en " + file + ".cifrado");
//declaración de objetos
byte[] buffer = new byte[1000]; //array de bytes
byte[] bufferCifrado;
fe = new FileInputStream(file); //objeto fichero de entrada
fs = new FileOutputStream(file + ".cifrado"); //fichero de salida
//lee el fichero de 1k en 1k y pasa los fragmentos leidos al cifrador
bytesLeidos = fe.read(buffer, 0, 1000);
while (bytesLeidos != -1) {//mientras no se llegue al final del fichero
//pasa texto claro al cifrador y lo cifra, asignándolo a bufferCifrado
bufferCifrado = cifrador.update(buffer, 0, bytesLeidos);
fs.write(bufferCifrado); //Graba el texto cifrado en fichero
bytesLeidos = fe.read(buffer, 0, 1000);
}
bufferCifrado = cifrador.doFinal(); //Completa el cifrado
fs.write(bufferCifrado); //Graba el final del texto cifrado, si lo hay
//Cierra ficheros
fe.close();
fs.close();
return clave;
}
//método que desencripta el fichero pasado como primer parámetro file1
//pasándole también la clave privada que necesita para desencriptar, key
//y deja el fichero desencriptado en el tercer parámetro file2
private static void descifrarFichero(String file1, SecretKey key, String file2) throws NoSuchAlgorithmException, NoSuchPaddingException, FileNotFoundException, IOException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException {
FileInputStream fe = null; //fichero de entrada
FileOutputStream fs = null; //fichero de salida
int bytesLeidos;
Cipher cifrador = Cipher.getInstance("DES");
//3.- Poner cifrador en modo DESCIFRADO o DESENCRIPTACIÓN
cifrador.init(Cipher.DECRYPT_MODE, key);
System.out.println("3.- Descifrar con DES el fichero: " + file1
+ ", y dejar en " + file2);
fe = new FileInputStream(file1);
fs = new FileOutputStream(file2);
byte[] bufferClaro;
byte[] buffer = new byte[1000]; //array de bytes
//lee el fichero de 1k en 1k y pasa los fragmentos leidos al cifrador
bytesLeidos = fe.read(buffer, 0, 1000);
while (bytesLeidos != -1) {//mientras no se llegue al final del fichero
//pasa texto cifrado al cifrador y lo descifra, asignándolo a bufferClaro
bufferClaro = cifrador.update(buffer, 0, bytesLeidos);
fs.write(bufferClaro); //Graba el texto claro en fichero
bytesLeidos = fe.read(buffer, 0, 1000);
}
bufferClaro = cifrador.doFinal(); //Completa el descifrado
fs.write(bufferClaro); //Graba el final del texto claro, si lo hay
//cierra archivos
fe.close();
fs.close();
}
//método que muestra bytes
public static void mostrarBytes(byte[] buffer) {
System.out.write(buffer, 0, buffer.length);
}
}
¿Cómo funciona RSA?
import java.io.IOException;
import java.security.*;
import javax.crypto.*;
//Encriptar y desencriptar un texto mediante clave pública RSA
public class CifradoRSA {
public static void main(String[] args) throws Exception {
System.out.println("Crear clave pública y privada");
//Crea e inicializa el generador de claves RSA
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(512);//tamaño de la clave
KeyPair clavesRSA = keyGen.generateKeyPair();
PrivateKey clavePrivada = clavesRSA.getPrivate();//obtiene clave privada
PublicKey clavePublica = clavesRSA.getPublic();//obtiene clave pública
//muestra las claves generadas
System.out.println("clavePublica: " + clavePublica);
System.out.println("clavePrivada: " + clavePrivada);
//texto a encriptar o cifrar
byte[] bufferClaro = "Este es el mensaje secreto\n".getBytes();
//Crea cifrador RSA
Cipher cifrador = Cipher.getInstance("RSA");
//Pone cifrador en modo ENCRIPTACIÓN utilizando la clave pública
cifrador.init(Cipher.ENCRYPT_MODE, clavePublica);
System.out.println("Cifrar con clave pública el Texto:");
mostrarBytes(bufferClaro);
//obtiene todo el texto cifrado
byte[] bufferCifrado = cifrador.doFinal(bufferClaro);
System.out.println("Texto CIFRADO");
mostrarBytes(bufferCifrado); //muestra texto cifrado
System.out.println("\n_______________________________");
//Pone cifrador en modo DESENCRIPTACIÓN utilizando la clave privada
cifrador.init(Cipher.DECRYPT_MODE, clavePrivada);
System.out.println("Descifrar con clave privada");
//obtiene el texto descifrado
bufferClaro = cifrador.doFinal(bufferCifrado);
System.out.println("Texto DESCIFRADO");
mostrarBytes(bufferClaro);//muestra texto descifrado
System.out.println("\n_______________________________");
}
public static void mostrarBytes(byte[] buffer) throws IOException {
System.out.write(buffer);
}
}
Proyecto en Intellij Idea de Criptografia
Uso en Kotlin:
Ejemplo de cifrado AES en Kotlin
Código de Cifrado AES en Kotlin
Programar un socket seguro:
Ejemplo: Servidor
Ejemplo: Cliente
Tarea de unidad 4
Más información:
Cifrado simétrico y asimétrico

Deja una respuesta
Lo siento, debes estar conectado para publicar un comentario.