Criptografía Java - Guía rápida

La criptografía es el arte y la ciencia de crear un criptosistema que sea capaz de brindar seguridad a la información.

La criptografía se ocupa de la protección real de los datos digitales. Se refiere al diseño de mecanismos basados ​​en algoritmos matemáticos que brindan servicios fundamentales de seguridad de la información. Puede pensar en la criptografía como el establecimiento de un gran conjunto de herramientas que contiene diferentes técnicas en aplicaciones de seguridad.

¿Qué es el criptoanálisis?

El arte y la ciencia de romper el texto cifrado se conoce como criptoanálisis.

El criptoanálisis es la rama hermana de la criptografía y ambos coexisten. El proceso criptográfico da como resultado el texto cifrado para su transmisión o almacenamiento. Implica el estudio de mecanismos criptográficos con la intención de romperlos. El criptoanálisis también se utiliza durante el diseño de las nuevas técnicas criptográficas para probar sus puntos fuertes de seguridad.

Primitivas de criptografía

Las primitivas de criptografía no son más que herramientas y técnicas de criptografía que se pueden utilizar de forma selectiva para proporcionar un conjunto de servicios de seguridad deseados.

  • Encryption
  • Funciones hash
  • Códigos de autenticación de mensajes (MAC)
  • Firmas digitales

Criptografía en Java

La Arquitectura de Criptografía de Java (JCA) es un conjunto de API para implementar conceptos de criptografía moderna como firmas digitales, resúmenes de mensajes, certificados, cifrado, generación y administración de claves, y generación segura de números aleatorios, etc.

Utilizando JCA, los desarrolladores pueden construir sus aplicaciones integrando la seguridad en ellas.

Para integrar la seguridad en sus aplicaciones en lugar de depender de los complicados algoritmos de seguridad, puede llamar fácilmente a las respectivas API proporcionadas en JCA para los servicios requeridos.

Las funciones hash son extremadamente útiles y aparecen en casi todas las aplicaciones de seguridad de la información.

Una función hash es una función matemática que convierte un valor de entrada numérico en otro valor numérico comprimido. La entrada a la función hash es de longitud arbitraria pero la salida siempre es de longitud fija.

Los valores devueltos por una función hash se llaman message digest o simplemente hash values. La siguiente imagen ilustra la función hash.

Java proporciona una clase llamada MessageDigestque pertenece al paquete java.security. Esta clase admite algoritmos como SHA-1, SHA 256, MD5 para convertir un mensaje de longitud arbitraria en un resumen de mensaje.

Para convertir un mensaje determinado en un resumen de mensajes, siga los pasos que se indican a continuación:

Paso 1: crear un objeto MessageDigest

La clase MessageDigest proporciona un método llamado getInstance(). Este método acepta una variable de cadena que especifica el nombre del algoritmo que se utilizará y devuelve un objeto MessageDigest que implementa el algoritmo especificado.

Cree el objeto MessageDigest usando el getInstance() método como se muestra a continuación.

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

Paso 2: pasar datos al objeto MessageDigest creado

Después de crear el objeto de resumen del mensaje, debe pasarle el mensaje / datos. Puede hacerlo utilizando elupdate() método del MessageDigest class, este método acepta una matriz de bytes que representa el mensaje y la agrega / pasa al objeto MessageDigest creado anteriormente.

md.update(msg.getBytes());

Paso 3: generar el resumen del mensaje

Puede generar el resumen del mensaje usando el digest() método de la clase MessageDigest este método calcula la función hash en el objeto actual y devuelve el resumen del mensaje en forma de matriz de bytes.

Genere el resumen del mensaje utilizando el método de resumen.

byte[] digest = md.digest();

Ejemplo

A continuación se muestra un ejemplo que lee datos de un archivo y genera un resumen de mensaje y lo imprime.

import java.security.MessageDigest;
import java.util.Scanner;

public class MessageDigestExample {
   public static void main(String args[]) throws Exception{
      //Reading data from user
      Scanner sc = new Scanner(System.in);
      System.out.println("Enter the message");
      String message = sc.nextLine();
	  
      //Creating the MessageDigest object  
      MessageDigest md = MessageDigest.getInstance("SHA-256");

      //Passing data to the created MessageDigest Object
      md.update(message.getBytes());
      
      //Compute the message digest
      byte[] digest = md.digest();      
      System.out.println(digest);  
     
      //Converting the byte array in to HexString format
      StringBuffer hexString = new StringBuffer();
      
      for (int i = 0;i<digest.length;i++) {
         hexString.append(Integer.toHexString(0xFF & digest[i]));
      }
      System.out.println("Hex format : " + hexString.toString());     
   }
}

Salida

El programa anterior genera la siguiente salida:

Enter the message
Hello how are you
[B@55f96302
Hex format: 2953d33828c395aebe8225236ba4e23fa75e6f13bd881b9056a3295cbd64d3

MAC (Mmensaje Aautenticación CEl algoritmo ode) es una técnica criptográfica de clave simétrica para proporcionar autenticación de mensajes. Para establecer el proceso MAC, el remitente y el receptor comparten una clave simétrica K.

Básicamente, una MAC es una suma de comprobación encriptada generada en el mensaje subyacente que se envía junto con un mensaje para garantizar la autenticación del mensaje.

El proceso de utilizar MAC para la autenticación se muestra en la siguiente ilustración:

En Java el Mac clase de la javax.cryptoEl paquete proporciona la funcionalidad del código de autenticación de mensajes. Siga los pasos que se indican a continuación para crear un código de autenticación de mensajes utilizando esta clase.

Paso 1: crear un objeto KeyGenerator

los KeyGenerator la clase proporciona getInstance() método que acepta una variable de cadena que representa el algoritmo de generación de claves requerido y devuelve un KeyGenerator objeto que genera claves secretas.

Crear KeyGenerator objeto usando el getInstance() método como se muestra a continuación.

//Creating a KeyGenerator object
KeyGenerator keyGen = KeyGenerator.getInstance("DES");

Paso 2: crear un objeto SecureRandom

los SecureRandom clase de la java.SecurityEl paquete proporciona un potente generador de números aleatorios que se utiliza para generar números aleatorios en Java. Cree una instancia de esta clase como se muestra a continuación.

//Creating a SecureRandom object
SecureRandom secRandom = new SecureRandom();

Paso 3: inicializar KeyGenerator

los KeyGenerator la clase proporciona un método llamado init() este método acepta el SecureRandom objeto e inicializa la corriente KeyGenerator.

Inicialice el objeto KeyGenerator creado en el paso anterior usando este método.

//Initializing the KeyGenerator
keyGen.init(secRandom);

Paso 4: generar clave

Generar clave usando generateKey() método del KeyGenerator clase como se muestra a continuación.

//Creating/Generating a key
Key key = keyGen.generateKey();

Paso 5: inicializa el objeto Mac

los init() El método de la clase Mac acepta un objeto Key e inicializa el objeto Mac actual usando la clave dada.

//Initializing the Mac object
mac.init(key);

Paso 6: finalice la operación de mac

los doFinal()El método de la clase Mac se utiliza para finalizar la operación Mac. Pase los datos necesarios en forma de matriz de bytes a este método y finalice la operación como se muestra a continuación.

//Computing the Mac
String msg = new String("Hi how are you");
byte[] bytes = msg.getBytes();
byte[] macResult = mac.doFinal(bytes);

Ejemplo

El siguiente ejemplo demuestra la generación de código de autenticación de mensajes (MAC) utilizando JCA. Aquí, tomamos un simple mensaje "Hola cómo estás" y generamos una Mac para ese mensaje.

import java.security.Key;
import java.security.SecureRandom;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;

public class MacSample {
   public static void main(String args[]) throws Exception{
      //Creating a KeyGenerator object
      KeyGenerator keyGen = KeyGenerator.getInstance("DES");

      //Creating a SecureRandom object
      SecureRandom secRandom = new SecureRandom();

      //Initializing the KeyGenerator
      keyGen.init(secRandom);

      //Creating/Generating a key
      Key key = keyGen.generateKey();	 

      //Creating a Mac object
      Mac mac = Mac.getInstance("HmacSHA256");

      //Initializing the Mac object
      mac.init(key);

      //Computing the Mac
      String msg = new String("Hi how are you");
      byte[] bytes = msg.getBytes();      
      byte[] macResult = mac.doFinal(bytes);

      System.out.println("Mac result:");
      System.out.println(new String(macResult));     
   }
}

Salida

El programa anterior generará la siguiente salida:

Mac result:
HÖ„^ǃÎ_Utbh…?š_üzØSSÜh_ž_œa0ŽV?

Un criptosistema es una implementación de técnicas criptográficas y la infraestructura que las acompaña para proporcionar servicios de seguridad de la información. Un criptosistema también se conoce comocipher system.

Los diversos componentes de un criptosistema básico son Plaintext, Encryption Algorithm, Ciphertext, Decryption Algorithm, Clave de cifrado y Clave de descifrado.

Dónde,

  • Encryption Keyes un valor que conoce el remitente. El remitente ingresa la clave de cifrado en el algoritmo de cifrado junto con el texto sin formato para calcular el texto cifrado.

  • Decryption Keyes un valor que conoce el receptor. La clave de descifrado está relacionada con la clave de cifrado, pero no siempre es idéntica a ella. El receptor ingresa la clave de descifrado en el algoritmo de descifrado junto con el texto cifrado para calcular el texto sin formato.

Fundamentalmente, existen dos tipos de claves / criptosistemas basados ​​en el tipo de algoritmos de cifrado-descifrado.

Cifrado de clave simétrica

El proceso de cifrado donde same keys are used for encrypting and decrypting la información se conoce como cifrado de clave simétrica.

El estudio de criptosistemas simétricos se conoce como symmetric cryptography. Los criptosistemas simétricos también se denominan a vecessecret key cryptosystems.

A continuación, se muestran algunos ejemplos comunes de cifrado de clave simétrica:

  • Estándar de cifrado digital (DES)
  • Triple-DES (3DES)
  • IDEA
  • BLOWFISH

Cifrado de clave asimétrica

El proceso de cifrado donde different keys are used for encrypting and decrypting the informationse conoce como cifrado de clave asimétrica. Aunque las claves son diferentes, están relacionadas matemáticamente y, por lo tanto, es factible recuperar el texto plano descifrando el texto cifrado.

Las claves y certificados utilizados / generados se almacenan en una base de datos denominada almacén de claves. De forma predeterminada, esta base de datos se almacena en un archivo llamado.keystore.

Puede acceder al contenido de esta base de datos utilizando el KeyStore clase de la java.securitypaquete. Esto gestiona tres entradas diferentes, a saber, PrivateKeyEntry, SecretKeyEntry, TrustedCertificateEntry.

  • PrivateKeyEntry
  • SecretKeyEntry
  • TrustedCertificateEntry

Almacenamiento de una clave en el almacén de claves

En esta sección, aprenderemos cómo almacenar una clave en un almacén de claves. Para almacenar una clave en el almacén de claves, siga los pasos que se indican a continuación.

Paso 1: crear un objeto KeyStore

los getInstance() método del KeyStore clase de la java.security El paquete acepta un valor de cadena que representa el tipo de almacén de claves y devuelve un objeto KeyStore.

Cree un objeto de la clase KeyStore utilizando el getInstance() método como se muestra a continuación.

//Creating the KeyStore object
KeyStore keyStore = KeyStore.getInstance("JCEKS");

Paso 2: Cargue el objeto KeyStore

los load() El método de la clase KeyStore acepta un objeto FileInputStream que representa el archivo del almacén de claves y un parámetro String que especifica la contraseña del almacén de claves.

En general, el KeyStore se almacena en el archivo llamado cacerts, en la ubicación C:/Program Files/Java/jre1.8.0_101/lib/security/ y su contraseña predeterminada es changeit, cárguelo usando el load() método como se muestra a continuación.

//Loading the KeyStore object
char[] password = "changeit".toCharArray();
String path = "C:/Program Files/Java/jre1.8.0_101/lib/security/cacerts";
java.io.FileInputStream fis = new FileInputStream(path);
keyStore.load(fis, password);

Paso 3: Cree el objeto KeyStore.ProtectionParameter

Cree una instancia de KeyStore.ProtectionParameter como se muestra a continuación.

//Creating the KeyStore.ProtectionParameter object
KeyStore.ProtectionParameter protectionParam = new KeyStore.PasswordProtection(password);

Paso 4: crea un objeto SecretKey

Crea el SecretKey (interfaz) objeto creando una instancia de su subclase SecretKeySpec. Mientras crea una instancia, debe pasar la contraseña y el algoritmo como parámetros a su constructor, como se muestra a continuación.

//Creating SecretKey object
SecretKey mySecretKey = new SecretKeySpec(new String(keyPassword).getBytes(), "DSA");

Paso 5: Cree un objeto SecretKeyEntry

Crea un objeto del SecretKeyEntry clase pasando el SecretKey objeto creado en el paso anterior como se muestra a continuación.

//Creating SecretKeyEntry object
KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(mySecretKey);

Paso 6: establezca una entrada en KeyStore

los setEntry() método del KeyStore La clase acepta un parámetro String que representa el alias de entrada del almacén de claves, un SecretKeyEntry object, un objeto ProtectionParameter y, almacena la entrada bajo el alias dado.

Establezca la entrada al almacén de claves mediante el setEntry() método como se muestra a continuación.

//Set the entry to the keystore
keyStore.setEntry("secretKeyAlias", secretKeyEntry, protectionParam);

Example

El siguiente ejemplo almacena claves en el almacén de claves existente en el archivo "cacerts" (sistema operativo Windows 10).

import java.io.FileInputStream;
import java.security.KeyStore;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class StoringIntoKeyStore{
   public static void main(String args[]) throws Exception {
      //Creating the KeyStore object
      KeyStore keyStore = KeyStore.getInstance("JCEKS");

      //Loading the KeyStore object
      char[] password = "changeit".toCharArray();
      String path = "C:/Program Files/Java/jre1.8.0_101/lib/security/cacerts";
      java.io.FileInputStream fis = new FileInputStream(path);
      keyStore.load(fis, password);
      
      //Creating the KeyStore.ProtectionParameter object
      KeyStore.ProtectionParameter protectionParam = new KeyStore.PasswordProtection(password);

      //Creating SecretKey object
      SecretKey mySecretKey = new SecretKeySpec("myPassword".getBytes(), "DSA");
      
      //Creating SecretKeyEntry object
      KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(mySecretKey);
      keyStore.setEntry("secretKeyAlias", secretKeyEntry, protectionParam);

      //Storing the KeyStore object
      java.io.FileOutputStream fos = null;
      fos = new java.io.FileOutputStream("newKeyStoreName");
      keyStore.store(fos, password);
      System.out.println("data stored");
   }
}

Output

El programa anterior genera la siguiente salida:

System.out.println("data stored");

En este capítulo, aprenderemos cómo recuperar una clave del almacén de claves utilizando criptografía Java.

Para recuperar una clave del almacén de claves, siga los pasos que se indican a continuación.

Paso 1: crear un objeto KeyStore

los getInstance() método del KeyStore clase de la java.security El paquete acepta un valor de cadena que representa el tipo de almacén de claves y devuelve un objeto KeyStore.

Cree un objeto de la clase KeyStore utilizando este método como se muestra a continuación.

//Creating the KeyStore object
KeyStore keyStore = KeyStore.getInstance("JCEKS");

Paso 2: Cargue el objeto KeyStore

los load() El método de la clase KeyStore acepta un FileInputStream objeto que representa el archivo de almacén de claves y un parámetro de cadena que especifica la contraseña del almacén de claves.

En general, el KeyStore se almacena en el archivo llamado cacerts, en la ubicación C:/Program Files/Java/jre1.8.0_101/lib/security/ y su contraseña predeterminada es changeit, cárguelo usando el load() método como se muestra a continuación.

//Loading the KeyStore object
char[] password = "changeit".toCharArray();
String path = "C:/Program Files/Java/jre1.8.0_101/lib/security/cacerts";
java.io.FileInputStream fis = new FileInputStream(path);
keyStore.load(fis, password);

Paso 3: Cree el objeto KeyStore.ProtectionParameter

Cree una instancia de KeyStore.ProtectionParameter como se muestra a continuación.

//Creating the KeyStore.ProtectionParameter object
KeyStore.ProtectionParameter protectionParam = new KeyStore.PasswordProtection(password);

Paso 4: crea un objeto SecretKey

Crea el SecretKey (interfaz) objeto creando una instancia de su subclase SecretKeySpec. Mientras crea una instancia, debe pasar la contraseña y el algoritmo como parámetros a su constructor, como se muestra a continuación.

//Creating SecretKey object
SecretKey mySecretKey = new SecretKeySpec(new String(keyPassword).getBytes(), "DSA");

Paso 5: Cree un objeto SecretKeyEntry

Crea un objeto del SecretKeyEntry clase pasando el SecretKey objeto creado en el paso anterior como se muestra a continuación.

//Creating SecretKeyEntry object
KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(mySecretKey);

Paso 6: establezca una entrada en KeyStore

los setEntry() método del KeyStore La clase acepta un parámetro String que representa el alias de entrada del almacén de claves, un SecretKeyEntry object, un objeto ProtectionParameter y, almacena la entrada bajo el alias dado.

Establezca la entrada al almacén de claves mediante el setEntry() método como se muestra a continuación.

//Set the entry to the keystore
keyStore.setEntry("secretKeyAlias", secretKeyEntry, protectionParam);

Paso 7: Cree el objeto KeyStore.SecretKeyEntry

los getEntry() El método de la clase KeyStore acepta un alias (parámetro String) y un objeto de la clase ProtectionParameter como parámetros y devuelve un KeyStoreEntry objeto, entonces puedes lanzarlo en KeyStore.SecretKeyEntry objeto.

Cree un objeto de la clase KeyStore.SecretKeyEntry pasando el alias de la clave requerida y el objeto de parámetro de protección creado en los pasos anteriores, al getEntry() método como se muestra a continuación.

//Creating the KeyStore.SecretKeyEntry object
KeyStore.SecretKeyEntry secretKeyEnt = (KeyStore.SecretKeyEntry)keyStore.getEntry("secretKeyAlias", protectionParam);

Paso 8: crea el objeto clave de la entrada recuperada

los getSecretKey() método del SecretKeyEntryLa clase devuelve un objeto SecretKey. Con este método, cree un objeto SecretKey como se muestra a continuación.

//Creating SecretKey object
SecretKey mysecretKey = secretKeyEnt.getSecretKey();      
System.out.println(mysecretKey);

Ejemplo

El siguiente ejemplo muestra cómo recuperar claves de un almacén de claves. Aquí, almacenamos una clave en un almacén de claves, que se encuentra en el archivo "cacerts" (sistema operativo Windows 10), la recuperamos y mostramos algunas de sus propiedades, como el algoritmo utilizado para generar la clave y el formato de la clave recuperada.

import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.KeyStore.ProtectionParameter;
import java.security.KeyStore.SecretKeyEntry;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class RetrievingFromKeyStore{
   public static void main(String args[]) throws Exception{
      //Creating the KeyStore object
      KeyStore keyStore = KeyStore.getInstance("JCEKS");

      //Loading the the KeyStore object
      char[] password = "changeit".toCharArray();
      java.io.FileInputStream fis = new FileInputStream(
         "C:/Program Files/Java/jre1.8.0_101/lib/security/cacerts");
      
      keyStore.load(fis, password);
      
      //Creating the KeyStore.ProtectionParameter object
      ProtectionParameter protectionParam = new KeyStore.PasswordProtection(password);

      //Creating SecretKey object
      SecretKey mySecretKey = new SecretKeySpec("myPassword".getBytes(), "DSA");
      
      //Creating SecretKeyEntry object
      SecretKeyEntry secretKeyEntry = new SecretKeyEntry(mySecretKey);
      keyStore.setEntry("secretKeyAlias", secretKeyEntry, protectionParam);

      //Storing the KeyStore object
      java.io.FileOutputStream fos = null;
      fos = new java.io.FileOutputStream("newKeyStoreName");
      keyStore.store(fos, password);
      
      //Creating the KeyStore.SecretKeyEntry object
      SecretKeyEntry secretKeyEnt = (SecretKeyEntry)keyStore.getEntry("secretKeyAlias", protectionParam);

      //Creating SecretKey object
      SecretKey mysecretKey = secretKeyEnt.getSecretKey();      
      System.out.println("Algorithm used to generate key : "+mysecretKey.getAlgorithm());   
      System.out.println("Format used for the key: "+mysecretKey.getFormat());
   }
}

Salida

El programa anterior genera la siguiente salida:

Algorithm used to generate key: DSA
Format of the key: RAW

Java proporciona KeyGenerator class esta clase se utiliza para generar claves secretas y los objetos de esta clase son reutilizables.

Para generar claves usando la clase KeyGenerator, siga los pasos que se indican a continuación.

Paso 1: crear un objeto KeyGenerator

los KeyGenerator la clase proporciona getInstance() método que acepta una variable String que representa el algoritmo de generación de claves requerido y devuelve un objeto KeyGenerator que genera claves secretas.

Crear KeyGenerator objeto usando el getInstance() método como se muestra a continuación.

//Creating a KeyGenerator object
KeyGenerator keyGen = KeyGenerator.getInstance("DES");

Paso 2: crear un objeto SecureRandom

los SecureRandom clase de la java.SecurityEl paquete proporciona un potente generador de números aleatorios que se utiliza para generar números aleatorios en Java. Cree una instancia de esta clase como se muestra a continuación.

//Creating a SecureRandom object
SecureRandom secRandom = new SecureRandom();

Paso 3: inicializar KeyGenerator

los KeyGenerator la clase proporciona un método llamado init() este método acepta el objeto SecureRandom e inicializa el actual KeyGenerator.

Inicialice el objeto KeyGenerator creado en el paso anterior usando el init() método.

//Initializing the KeyGenerator
keyGen.init(secRandom);

Ejemplo

El siguiente ejemplo demuestra la generación de claves de la clave secreta utilizando la clase KeyGenerator del javax.crypto paquete.

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;

import java.security.Key;
import java.security.SecureRandom;

public class KeyGeneratorExample {
   public static void main(String args[]) throws Exception{
      //Creating a KeyGenerator object
      KeyGenerator keyGen = KeyGenerator.getInstance("DES");
      
      //Creating a SecureRandom object
      SecureRandom secRandom = new SecureRandom();
      
      //Initializing the KeyGenerator
      keyGen.init(secRandom);
      
      //Creating/Generating a key
      Key key = keyGen.generateKey();
      
      System.out.println(key);      
      Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");      
      cipher.init(cipher.ENCRYPT_MODE, key);      

      String msg = new String("Hi how are you");
      byte[] bytes = cipher.doFinal(msg.getBytes());      
      System.out.println(bytes);      
   }
}

Salida

El programa anterior genera la siguiente salida:

com.sun.crypto.provider.DESKey@18629
[B@2ac1fdc4

Java proporciona la KeyPairGeneratorclase. Esta clase se utiliza para generar pares de claves públicas y privadas. Para generar claves usando elKeyPairGenerator clase, siga los pasos que se indican a continuación.

Paso 1: crear un objeto KeyPairGenerator

los KeyPairGenerator la clase proporciona getInstance() método que acepta una variable String que representa el algoritmo de generación de claves requerido y devuelve un objeto KeyPairGenerator que genera claves.

Crear KeyPairGenerator objeto usando el getInstance() método como se muestra a continuación.

//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");

Paso 2: inicializar el objeto KeyPairGenerator

los KeyPairGenerator la clase proporciona un método llamado initialize()este método se utiliza para inicializar el generador de pares de claves. Este método acepta un valor entero que representa el tamaño de la clave.

Inicialice el objeto KeyPairGenerator creado en el paso anterior usando este método como se muestra a continuación.

//Initializing the KeyPairGenerator
keyPairGen.initialize(2048);

Paso 3: Genere el KeyPairGenerator

Puede generar el KeyPair utilizando el generateKeyPair() método del KeyPairGeneratorclase. Genere el par de claves utilizando este método como se muestra a continuación.

//Generate the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();

Paso 4: obtenga la clave privada / clave pública

Puede obtener la clave privada del objeto KeyPair generado utilizando el getPrivate() método como se muestra a continuación.

//Getting the private key from the key pair
PrivateKey privKey = pair.getPrivate();

Puede obtener la clave pública del objeto KeyPair generado utilizando el getPublic() método como se muestra a continuación.

//Getting the public key from the key pair
PublicKey publicKey = pair.getPublic();

Ejemplo

El siguiente ejemplo demuestra la generación de claves de la clave secreta utilizando la clase KeyPairGenerator del javax.crypto paquete.

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;

public class KeyPairGenertor {
   public static void main(String args[]) throws Exception{
      //Creating KeyPair generator object
      KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");
      
      //Initializing the KeyPairGenerator
      keyPairGen.initialize(2048);
      
      //Generating the pair of keys
      KeyPair pair = keyPairGen.generateKeyPair();
      
      //Getting the private key from the key pair
      PrivateKey privKey = pair.getPrivate();   
      
      //Getting the public key from the key pair
      PublicKey publicKey = pair.getPublic(); 
      System.out.println("Keys generated");
   }
}

Salida

El programa anterior genera la siguiente salida:

Keys generated

Las firmas digitales nos permiten verificar el autor, fecha y hora de las firmas, autenticar el contenido del mensaje. También incluye la función de autenticación para capacidades adicionales.

Ventajas de la firma digital

En este apartado conoceremos los diferentes motivos que exigen el uso de la firma digital. Hay varias razones para implementar firmas digitales en las comunicaciones:

Autenticación

Las firmas digitales ayudan a autenticar las fuentes de los mensajes. Por ejemplo, si la sucursal de un banco envía un mensaje a la oficina central, solicitando un cambio en el saldo de una cuenta. Si la oficina central no pudo autenticar que el mensaje se envía desde una fuente autorizada, actuar de acuerdo con dicha solicitud podría ser un grave error.

Integridad

Una vez que se firma el mensaje, cualquier cambio en el mensaje invalidaría la firma.

No repudio

Por esta propiedad, cualquier entidad que haya firmado alguna información no podrá en un momento posterior negar haberla firmado.

Creando la firma digital

Aprendamos ahora a crear una firma digital. Puede crear una firma digital utilizando Java siguiendo los pasos que se indican a continuación.

Paso 1: crear un objeto KeyPairGenerator

los KeyPairGenerator la clase proporciona getInstance() método que acepta una variable String que representa el algoritmo de generación de claves requerido y devuelve un objeto KeyPairGenerator que genera claves.

Crear KeyPairGenerator objeto usando el getInstance() método como se muestra a continuación.

//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");

Paso 2: inicializar el objeto KeyPairGenerator

los KeyPairGenerator la clase proporciona un método llamado initialize()este método se utiliza para inicializar el generador de pares de claves. Este método acepta un valor entero que representa el tamaño de la clave.

Inicialice el objeto KeyPairGenerator creado en el paso anterior usando el initialize() método como se muestra a continuación.

//Initializing the KeyPairGenerator
keyPairGen.initialize(2048);

Paso 3: Genere el KeyPairGenerator

Puede generar el KeyPair utilizando el generateKeyPair()método. Genere el par de claves usando elgenerateKeyPair() método como se muestra a continuación.

//Generate the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();

Paso 4: obtenga la clave privada del par

Puede obtener la clave privada del objeto KeyPair generado utilizando el getPrivate() método.

Obtenga la clave privada usando el getPrivate() método como se muestra a continuación.

//Getting the private key from the key pair
PrivateKey privKey = pair.getPrivate();

Paso 5: crea un objeto de firma

los getInstance() método del Signature La clase acepta un parámetro de cadena que representa el algoritmo de firma requerido y devuelve el objeto Signature correspondiente.

Cree un objeto de la clase Signature usando el getInstance() método.

//Creating a Signature object
Signature sign = Signature.getInstance("SHA256withDSA");

Paso 6: inicializar el objeto Signature

los initSign() El método de la clase Signature acepta un PrivateKey objeto e inicializa el objeto Signature actual.

Inicialice el objeto Signature creado en el paso anterior usando el initSign() método como se muestra a continuación.

//Initialize the signature
sign.initSign(privKey);

Paso 7: agregue datos al objeto Firma

los update() El método de la clase Signature acepta una matriz de bytes que representa los datos que se van a firmar o verificar y actualiza el objeto actual con los datos proporcionados.

Actualice el objeto Signature inicializado pasando los datos a firmar al update() método en forma de matriz de bytes como se muestra a continuación.

byte[] bytes = "Hello how are you".getBytes();      

//Adding data to the signature
sign.update(bytes);

Paso 8: Calcule la firma

los sign() método del Signature class devuelve los bytes de firma de los datos actualizados.

Calcule la Firma usando el sign() método como se muestra a continuación.

//Calculating the signature
byte[] signature = sign.sign();

Example

El siguiente programa Java acepta un mensaje del usuario y genera una firma digital para el mensaje dado.

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.Scanner;

public class CreatingDigitalSignature {
   public static void main(String args[]) throws Exception {
      //Accepting text from user
      Scanner sc = new Scanner(System.in);
      System.out.println("Enter some text");
      String msg = sc.nextLine();
      
      //Creating KeyPair generator object
      KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");
      
      //Initializing the key pair generator
      keyPairGen.initialize(2048);
      
      //Generate the pair of keys
      KeyPair pair = keyPairGen.generateKeyPair();
      
      //Getting the private key from the key pair
      PrivateKey privKey = pair.getPrivate();
      
      //Creating a Signature object
      Signature sign = Signature.getInstance("SHA256withDSA");
      
      //Initialize the signature
      sign.initSign(privKey);
      byte[] bytes = "msg".getBytes();
      
      //Adding data to the signature
      sign.update(bytes);
      
      //Calculating the signature
      byte[] signature = sign.sign();
      
      //Printing the signature
      System.out.println("Digital signature for given text: "+new String(signature, "UTF8"));
   }
}

Output

El programa anterior genera la siguiente salida:

Enter some text
Hi how are you
Digital signature for given text: 0=@gRD???-?.???? /yGL?i??a!?

Puede crear una firma digital utilizando Java y verificarla siguiendo los pasos que se indican a continuación.

Paso 1: crear un objeto KeyPairGenerator

los KeyPairGenerator la clase proporciona getInstance() método que acepta una variable String que representa el algoritmo de generación de claves requerido y devuelve un objeto KeyPairGenerator que genera claves.

Crear KeyPairGenerator objeto usando el getInstance() método como se muestra a continuación.

//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");

Paso 2: inicializar el objeto KeyPairGenerator

los KeyPairGenerator la clase proporciona un método llamado initialize()método. Este método se utiliza para inicializar el generador de pares de claves. Este método acepta un valor entero que representa el tamaño de la clave.

Inicialice el objeto KeyPairGenerator creado en el paso anterior usando el initialize() método como se muestra a continuación.

//Initializing the KeyPairGenerator
keyPairGen.initialize(2048);

Paso 3: Genere el KeyPairGenerator

Puede generar el KeyPair utilizando el generateKeyPair()método. Genere el par de claves utilizando este método como se muestra a continuación.

//Generate the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();

Paso 4: obtenga la clave privada del par

Puede obtener la clave privada del objeto KeyPair generado utilizando el getPrivate() método.

Obtenga la clave privada usando el getPrivate() método como se muestra a continuación.

//Getting the private key from the key pair
PrivateKey privKey = pair.getPrivate();

Paso 5: crea un objeto de firma

los getInstance() método del Signature La clase acepta un parámetro de cadena que representa el algoritmo de firma requerido y devuelve el objeto Signature correspondiente.

Cree un objeto de la clase Signature usando el getInstance() método.

//Creating a Signature object
Signature sign = Signature.getInstance("SHA256withDSA");

Paso 6: inicializar el objeto Signature

los initSign() El método de la clase Signature acepta un PrivateKey objeto e inicializa el objeto Signature actual.

Inicialice el objeto Signature creado en el paso anterior usando el initSign() método como se muestra a continuación.

//Initialize the signature
sign.initSign(privKey);

Paso 7: agregue datos al objeto Firma

los update() El método de la clase Signature acepta una matriz de bytes que representa los datos que se van a firmar o verificar y actualiza el objeto actual con los datos proporcionados.

Actualice el objeto Signature inicializado pasando los datos a firmar al update() método en forma de matriz de bytes como se muestra a continuación.

byte[] bytes = "Hello how are you".getBytes();      

//Adding data to the signature
sign.update(bytes);

Paso 8: Calcule la firma

los sign() método del Signature class devuelve los bytes de firma de los datos actualizados.

Calcule la firma utilizando el método sign () como se muestra a continuación.

//Calculating the signature
byte[] signature = sign.sign();

Paso 9: inicializar el objeto de firma para su verificación

Para verificar un objeto Signature, primero debe inicializarlo usando el initVerify() método el método acepta un PublicKey objeto.

Por lo tanto, inicialice el objeto Signature para su verificación utilizando el initVerify() método como se muestra a continuación.

//Initializing the signature
sign.initVerify(pair.getPublic());

Paso 10: actualice los datos a verificar

Actualice el objeto inicializado (para verificación) con los datos que se verificarán utilizando el método de actualización como se muestra a continuación.

//Update the data to be verified
sign.update(bytes);

Paso 11: verificar la firma

los verify()El método de la clase Signature acepta otro objeto de firma y lo verifica con el actual. Si se produce una coincidencia, devuelve verdadero; de lo contrario, devuelve falso.

Verifique la firma usando este método como se muestra a continuación.

//Verify the signature
boolean bool = sign.verify(signature);

Ejemplo

El siguiente programa Java acepta un mensaje del usuario, genera una firma digital para el mensaje dado y lo verifica.

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.Signature;

import java.util.Scanner;

public class SignatureVerification {
   public static void main(String args[]) throws Exception{
      //Creating KeyPair generator object
      KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");
	      
      //Initializing the key pair generator
      keyPairGen.initialize(2048);
	      
      //Generate the pair of keys
      KeyPair pair = keyPairGen.generateKeyPair();
      
      //Getting the privatekey from the key pair
      PrivateKey privKey = pair.getPrivate();

      //Creating a Signature object
      Signature sign = Signature.getInstance("SHA256withDSA");

      //Initializing the signature
      sign.initSign(privKey);
      byte[] bytes = "Hello how are you".getBytes();
      
      //Adding data to the signature
      sign.update(bytes);
      
      //Calculating the signature
      byte[] signature = sign.sign();      
      
      //Initializing the signature
      sign.initVerify(pair.getPublic());
      sign.update(bytes);
      
      //Verifying the signature
      boolean bool = sign.verify(signature);
      
      if(bool) {
         System.out.println("Signature verified");   
      } else {
         System.out.println("Signature failed");
      }
   }
}

Salida

El programa anterior genera la siguiente salida:

Signature verified

Puede cifrar datos dados utilizando la clase Cipher del javax.cryptopaquete. Siga los pasos que se detallan a continuación para cifrar datos determinados con Java.

Paso 1: crear un objeto KeyPairGenerator

los KeyPairGenerator la clase proporciona getInstance() método que acepta una variable String que representa el algoritmo de generación de claves requerido y devuelve un objeto KeyPairGenerator que genera claves.

Crear KeyPairGenerator objeto usando el getInstance() método como se muestra a continuación.

//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");

Paso 2: inicializar el objeto KeyPairGenerator

los KeyPairGenerator la clase proporciona un método llamado initialize()este método se utiliza para inicializar el generador de pares de claves. Este método acepta un valor entero que representa el tamaño de la clave.

Inicialice el objeto KeyPairGenerator creado en el paso anterior usando el initialize() método como se muestra a continuación.

//Initializing the KeyPairGenerator
keyPairGen.initialize(2048);

Paso 3: Genere el KeyPairGenerator

Puede generar el KeyPair utilizando el generateKeyPair() método del KeyPairGeneratorclase. Genere el par de claves utilizando este método como se muestra a continuación.

//Generate the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();

Paso 4: Obtén la clave pública

Puede obtener la clave pública de la generada KeyPair objeto usando el getPublic() método como se muestra a continuación.

Obtenga la clave pública usando este método como se muestra a continuación.

//Getting the public key from the key pair
PublicKey publicKey = pair.getPublic();

Paso 5: Crea un objeto Cipher

los getInstance() método de Cipher La clase acepta una variable String que representa la transformación requerida y devuelve un objeto Cipher que implementa la transformación dada.

Cree el objeto Cipher usando el getInstance() método como se muestra a continuación.

//Creating a Cipher object
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

Paso 6: inicializar el objeto Cipher

los init() método del Cipher La clase acepta dos parámetros: un parámetro entero que representa el modo de operación (cifrar / descifrar) y un objeto Clave que representa la clave pública.

Inicialice el objeto Cypher usando el init() método como se muestra a continuación.

//Initializing a Cipher object
cipher.init(Cipher.ENCRYPT_MODE, publicKey);

Paso 7: agregar datos al objeto Cipher

los update() El método de la clase Cipher acepta una matriz de bytes que representa los datos a cifrar y actualiza el objeto actual con los datos proporcionados.

Actualice el objeto Cipher inicializado pasando los datos al update() método en forma de matriz de bytes como se muestra a continuación.

//Adding data to the cipher
byte[] input = "Welcome to Tutorialspoint".getBytes();	  
cipher.update(input);

Paso 8: cifre los datos

los doFinal()El método de la clase Cipher completa la operación de cifrado. Por lo tanto, finalice el cifrado utilizando este método como se muestra a continuación.

//Encrypting the data
byte[] cipherText = cipher.doFinal();

Ejemplo

El siguiente programa Java acepta texto del usuario, lo encripta utilizando el algoritmo RSA e imprime el formato encriptado del texto dado.

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Signature;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;

public class CipherSample {
   public static void main(String args[]) throws Exception{
      //Creating a Signature object
      Signature sign = Signature.getInstance("SHA256withRSA");
      
      //Creating KeyPair generator object
      KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
      
      //Initializing the key pair generator
      keyPairGen.initialize(2048);
      
      //Generating the pair of keys
      KeyPair pair = keyPairGen.generateKeyPair();      
	
      //Creating a Cipher object
      Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        
      //Initializing a Cipher object
      cipher.init(Cipher.ENCRYPT_MODE, pair.getPublic());
	  
      //Adding data to the cipher
      byte[] input = "Welcome to Tutorialspoint".getBytes();	  
      cipher.update(input);
	  
      //encrypting the data
      byte[] cipherText = cipher.doFinal();	 
      System.out.println(new String(cipherText, "UTF8"));
   }
}

Salida

El programa anterior genera la siguiente salida:

Encrypted Text: 
"???:]J_?]???;Xl??????*@??u???r??=T&???_?_??.??i?????(?$_f?zD??????ZGH??g??? g?E:_??bz^??f?~o???t?}??u=uzp\UI????Z??l[?G?3??Y?UAEfKT?f?O??N_?d__?????a_?15%?^? 'p?_?$,9"{??^??y??_?t???,?W?PCW??~??[?$??????e????f?Y-Zi__??_??w?_?&QT??`?`~?[?K_??_???

Puede descifrar los datos cifrados utilizando la clase Cipher del javax.cryptopaquete. Siga los pasos que se indican a continuación para descifrar datos dados usando Java.

Paso 1: crear un objeto KeyPairGenerator

los KeyPairGenerator la clase proporciona getInstance() método que acepta una variable String que representa el algoritmo de generación de claves requerido y devuelve un objeto KeyPairGenerator que genera claves.

Crear KeyPairGenerator objeto usando el getInstance() método como se muestra a continuación.

//Creating KeyPair generator object
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");

Paso 2: inicializar el objeto KeyPairGenerator

los KeyPairGenerator la clase proporciona un método llamado initialize()este método se utiliza para inicializar el generador de pares de claves. Este método acepta un valor entero que representa el tamaño de la clave.

Inicialice el objeto KeyPairGenerator creado en el paso anterior usando el initialize() método como se muestra a continuación.

//Initializing the KeyPairGenerator
keyPairGen.initialize(2048);

Paso 3: Genere el KeyPairGenerator

Puede generar el KeyPair utilizando el generateKeyPair() método del KeyPairGeneratorclase. Genere el par de claves utilizando este método como se muestra a continuación.

//Generate the pair of keys
KeyPair pair = keyPairGen.generateKeyPair();

Paso 4: Obtén la clave pública

Puede obtener la clave pública del objeto KeyPair generado utilizando el getPublic() método como se muestra a continuación.

//Getting the public key from the key pair
PublicKey publicKey = pair.getPublic();

Paso 5: Crea un objeto Cipher

los getInstance() método de Cipher La clase acepta una variable String que representa la transformación requerida y devuelve un objeto Cipher que implementa la transformación dada.

Cree el objeto Cipher usando el getInstance() método como se muestra a continuación.

//Creating a Cipher object
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

Paso 6: inicializar el objeto Cipher

los init() El método de la clase Cipher acepta dos parámetros.

  • Un parámetro entero que representa el modo de operación (cifrar / descifrar)
  • Objeto clave que representa la clave pública

Inicialice el objeto Cypher usando el init() método como se muestra a continuación.

//Initializing a Cipher object
cipher.init(Cipher.ENCRYPT_MODE, publicKey);

Paso 7: agregar datos al objeto Cipher

los update() El método de la clase Cipher acepta una matriz de bytes que representa los datos a cifrar y actualiza el objeto actual con los datos proporcionados.

Actualice el objeto Cipher inicializado pasando los datos al update() método en forma de matriz de bytes como se muestra a continuación.

//Adding data to the cipher
byte[] input = "Welcome to Tutorialspoint".getBytes();	  
cipher.update(input);

Paso 8: cifre los datos

los doFinal()El método de la clase Cipher completa la operación de cifrado. Por lo tanto, finalice el cifrado utilizando este método como se muestra a continuación.

//Encrypting the data
byte[] cipherText = cipher.doFinal();

Paso 9: inicialice el objeto Cipher para el descifrado

Para descifrar el cifrado cifrado en los pasos anteriores, debe inicializarlo para el descifrado.

Por lo tanto, inicialice el objeto de cifrado pasando los parámetros Cipher.DECRYPT_MODE y el objeto PrivateKey como se muestra a continuación.

//Initializing the same cipher for decryption
cipher.init(Cipher.DECRYPT_MODE, pair.getPrivate());

Paso 10: descifra los datos

Finalmente, descifre el texto cifrado usando el doFinal() método como se muestra a continuación.

//Decrypting the text
byte[] decipheredText = cipher.doFinal(cipherText);

Ejemplo

El siguiente programa Java acepta texto del usuario, lo encripta usando el algoritmo RSA e imprime el cifrado del texto dado, descifra el cifrado e imprime el texto descifrado nuevamente.

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Signature;

import javax.crypto.Cipher;

public class CipherDecrypt {
   public static void main(String args[]) throws Exception{
	   //Creating a Signature object
      Signature sign = Signature.getInstance("SHA256withRSA");
      
      //Creating KeyPair generator object
      KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
      
      //Initializing the key pair generator
      keyPairGen.initialize(2048);
      
      //Generate the pair of keys
      KeyPair pair = keyPairGen.generateKeyPair();   
      
      //Getting the public key from the key pair
      PublicKey publicKey = pair.getPublic();  

      //Creating a Cipher object
      Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

      //Initializing a Cipher object
      cipher.init(Cipher.ENCRYPT_MODE, publicKey);
	  
      //Add data to the cipher
      byte[] input = "Welcome to Tutorialspoint".getBytes();	  
      cipher.update(input);
	  
      //encrypting the data
      byte[] cipherText = cipher.doFinal();	 
      System.out.println( new String(cipherText, "UTF8"));

      //Initializing the same cipher for decryption
      cipher.init(Cipher.DECRYPT_MODE, pair.getPrivate());
      
      //Decrypting the text
      byte[] decipheredText = cipher.doFinal(cipherText);
      System.out.println(new String(decipheredText));
   }
}

Salida

El programa anterior genera la siguiente salida:

Encrypted Text:
]/[?F3?D?p
v?w?!?H???^?A??????P?u??FA?
?
???_?? ???_jMH-??>??OP?'?j?_?n`
?_??'`????o??_GL??g???g_f?????f|???LT?|?Vz_TDu#??\?<b,,?$C2???Bq?#?lDB`??g,^??K?_?v???`}
?;LX?a?_5e???#???_?6?/B&B_???^?__Ap^#_?q?IEh????_?,??*??]~_?_?D?
_y???lp??a?P_U{

Decrypted Text:
Welcome to Tutorialspoint