Skip to content

Latest commit

 

History

History
412 lines (335 loc) · 12 KB

2019-03-06.md

File metadata and controls

412 lines (335 loc) · 12 KB

Utilización de técnicas de programación segura:

  • Prácticas de programación segura.
  • Criptografía de clave pública y clave privada.
  • Principales aplicaciones de la criptografía.
  • Protocolos criptográficos.
  • Política de seguridad.
  • Programación de mecanismos de control de acceso.
  • Encriptación de información.
  • Protocolos seguros de comunicaciones.
  • Programación de aplicaciones con comunicaciones seguras.

CCN-STIC-807 – Criptografía de empleo en el ENS

Tipo de Algoritmo Acreditados por el CCN
Cifrado Simétrico TDEA (Triple Data Encryption Algorithm)
AES (Advanced Encryption Standard)
Algoritmos Asimétricos DSA (Digital Signature Algorithm)
ECDSA (Elliptic Curve Digital Signature Algorithm)
RSA (Criptosistema RSA)
ECIES (Elliptic Curve Integrated Encryption Scheme)
Intercambio de Clave DH o DHKA (Diffie-Hellman Key Agreement)
MQV (Menezes-Qu-Vanstone Key Agreement)
ECDH (Elliptic Curve Diffie-Hellman)
ECMQV (Elliptic Curve Menezes-Qu-Vanstone)
Funciones resumen (Hash) SHA-2 (Secure Hash Algorithm)
HMAC (Hash Message Authentication Code )

Cifrado

Cifrado simétrico

  • TDEA (Triple Data Encryption Algorithm)
  • AES (Advanced Encryption Standard)
/* Con clave aleatoria */

import javax.crypto.*;    
import java.security.*;  

public class Java {

	private static SecretKey key = null;         
	private static Cipher cipher = null; 

	public static void main(String[] args) throws Exception
	{
		KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
		keyGenerator.init(128);
		SecretKey secretKey = keyGenerator.generateKey();
		cipher = Cipher.getInstance("AES");

		String clearText = "hola";
		byte[] clearTextBytes = clearText.getBytes("UTF8");
		System.out.println("Texto en claro: " + clearText);
		System.out.println("Texto en Bytes claro: " + clearTextBytes);

		cipher.init(Cipher.ENCRYPT_MODE, secretKey);
		byte[] cipherBytes = cipher.doFinal(clearTextBytes);
		String cipherText = new String(cipherBytes, "UTF8");
		System.out.println("Texto cifrado: " + cipherText);
		System.out.println("Texto en Bytes cifrado: " + cipherBytes);

		cipher.init(Cipher.DECRYPT_MODE, secretKey);
		byte[] decryptedBytes = cipher.doFinal(cipherBytes);
		String decryptedText = new String(decryptedBytes, "UTF8");
		System.out.println("Texto descifrado: " + decryptedText);
		System.out.println("Texto en Bytes cifrado: " + decryptedBytes);
	}
}
/* Con clave añadida*/

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;
import java.util.Base64;

public class Java {

	private static Cipher cipher = null; 

	public static void main(String[] args) throws Exception{
		// Clave -> Clave en base 64
		// 1234567891234567 -> MTIzNDU2Nzg5MTIzNDU2Nw==
		// decode the base64 encoded string
		byte[] decodedKey = Base64.getDecoder().decode("MTIzNDU2Nzg5MTIzNDU2Nw==");
		
		// rebuild key using SecretKeySpec
		SecretKey originalKey = new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES");
		System.out.println("originalKey: " + decodedKey);
		
		cipher = Cipher.getInstance("AES");

		String clearText = "hola";
		byte[] clearTextBytes = clearText.getBytes("UTF8");
		System.out.println("Texto en claro: " + clearText);

		cipher.init(Cipher.ENCRYPT_MODE, originalKey);
		byte[] cipherBytes = cipher.doFinal(clearTextBytes);
		String cipherText = new String(cipherBytes, "UTF8");
		System.out.println("Texto cifrado: " + cipherText);

		cipher.init(Cipher.DECRYPT_MODE, originalKey);
		byte[] decryptedBytes = cipher.doFinal(cipherBytes);
		String decryptedText = new String(decryptedBytes, "UTF8");
		System.out.println("Texto descifrado: " + decryptedText);
	}
}

Algoritmos asimétricos

  • DSA (Digital Signature Algorithm)
  • ECDSA (Elliptic Curve Digital Signature Algorithm)
  • RSA (Criptosistema RSA)
import javax.crypto.*;
import java.security.*;
public class ExampleRSA {

	public static void main(String[] args) {
		try {
			KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA");
			KeyPair keypair = keygen.generateKeyPair();
			
			Cipher rsaCipher = Cipher.getInstance("RSA");
			
			String mensaje = "Mensajeo";
			
			rsaCipher.init(Cipher.ENCRYPT_MODE, keypair.getPrivate());
			byte[] mensajeCifrado = rsaCipher.doFinal(mensaje.getBytes("UTF8"));
			System.out.println(mensajeCifrado);
			
			rsaCipher.init(Cipher.DECRYPT_MODE, keypair.getPublic());
			byte[] mensajeDescifrado = rsaCipher.doFinal(mensajeCifrado);
			String mensajeDescifrado2 = new String(mensajeDescifrado, "UTF8");
			System.out.println(mensajeDescifrado2);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
  • ECIES (Elliptic Curve Integrated Encryption Scheme)

Ejemplos

Cifrar y descrifrar con clave secreta

import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;


public class Ejemplo10 {
	public static void main(String args[]) {
		try {
			//ALGORITMO DES
			KeyGenerator kg = KeyGenerator.getInstance("DES");
			Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding");
			Key key = kg.generateKey();
			
			c.init(Cipher.ENCRYPT_MODE, key);
			byte input[] = "Stand and unfold yourself".getBytes();
			byte encrypted[] = c.doFinal(input);
			byte iv[] = c.getIV();

			IvParameterSpec dps = new IvParameterSpec(iv);
			c.init(Cipher.DECRYPT_MODE, key, dps);
			byte output[] = c.doFinal(encrypted);
			System.out.println("The string was ");
			System.out.println(new String(output));
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		//ALGORITMO AES
		try {
			KeyGenerator kg = KeyGenerator.getInstance("AES");
			kg.init (128);
			SecretKey clave = kg.generateKey();
			
			Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding");
			c.init(Cipher.ENCRYPT_MODE, clave);
				
			//CIFRAMOS TEXTO
			byte textoPlano[] = "Esto es un Texto Plano".getBytes();
			byte textoCifrado[] = c.doFinal(textoPlano);
			System.out.println("Encriptado: "+ new String(textoCifrado));
			
		    //DESCIFRAMOS TEXTO					
			c.init(Cipher.DECRYPT_MODE, clave);		
			byte desencriptado[] = c.doFinal(textoCifrado);
			System.out.println("Desencriptado: "+ new String(desencriptado));
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
}

Cifrar y descifrar con clave pública

import java.security.*;
import javax.crypto.*;

public class Ejemplo11 {
	public static void main(String args[]) {
		
		try {
			//SE CREA EL PAR DE CLAVES		
			KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
			keyGen.initialize (1024);
			KeyPair par = keyGen.generateKeyPair();
			PrivateKey clavepriv = par.getPrivate();
			PublicKey clavepub = par.getPublic();
			
		
			Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
			c.init(Cipher.ENCRYPT_MODE, clavepub);

			//CIFRAMOS TEXTO
			byte textoPlano[] = "Esto es un Texto Plano".getBytes();
			byte textoCifrado[] = c.doFinal(textoPlano);
			System.out.println("Encriptado: "+ new String(textoCifrado));
			
		    //DESCIFRAMOS TEXTO					
			c.init(Cipher.DECRYPT_MODE, clavepriv);		
			byte desencriptado[] = c.doFinal(textoCifrado);
			System.out.println("Desencriptado: "+ new String(desencriptado));

		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
}

Cifrar y descifrar con clave pública

import java.security.*;
import javax.crypto.*;
public class Ejemplo12 {
	public static void main(String args[]) {		
		try {
			//SE CREA EL PAR DE CLAVES publica y privada	
			KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
			keyGen.initialize (1024);
			KeyPair par = keyGen.generateKeyPair();
			PrivateKey clavepriv = par.getPrivate();
			PublicKey clavepub = par.getPublic();			
		
			//SE CREA LA CLAVE SECRETA AES 
			KeyGenerator kg = KeyGenerator.getInstance("AES");
			kg.init (128);
			SecretKey clavesecreta = kg.generateKey();
			
			//SE ENVUELVE LA CLAVE SECRETA CON LA RSA PÚBLICA					
			Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
			c.init(Cipher.WRAP_MODE, clavepub);
			byte claveenvuelta[] = c.wrap(clavesecreta);				
			
			//CIFRAMOS TEXTO CON LA CLAVE SECRETA
			c = Cipher.getInstance("AES/ECB/PKCS5Padding");
			c.init(Cipher.ENCRYPT_MODE, clavesecreta);			
			byte textoPlano[] = "Esto es un Texto Plano".getBytes();
			byte textoCifrado[] = c.doFinal(textoPlano);
			System.out.println("Encriptado: "+ new String(textoCifrado));						
			
		    //SE DESENVUELVE LA CLAVE SECRETA CON LA CLAVE RSA PRIVADA	
			Cipher c2 = Cipher.getInstance("RSA/ECB/PKCS1Padding");
			c2.init(Cipher.UNWRAP_MODE, clavepriv);
			Key clavedesenvuelta= c2.unwrap(claveenvuelta, "AES", Cipher.SECRET_KEY);
			
			//DESCIFRAMOS TEXTO CON LA CLAVE DESENVUELTA
			c2 = Cipher.getInstance("AES/ECB/PKCS5Padding");
			c2.init(Cipher.DECRYPT_MODE, clavedesenvuelta);		
			byte desencriptado[] = c2.doFinal(textoCifrado);
			System.out.println("Desencriptado: "+ new String(desencriptado));

		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}//main
}//..Ejemplo12

Almacenar la clave secreta en un fichero

import java.io.*;
import java.security.*;
import javax.crypto.*;

public class AlmacenaClaveSecreta {
   public static void main(String[] args) {
	try {
		KeyGenerator kg = KeyGenerator.getInstance("AES");
		kg.init(128);

        //genera clave secreta
		SecretKey clave = kg.generateKey();

		ObjectOutputStream out = new ObjectOutputStream(
				       new FileOutputStream("Clave.secreta"));
		out.writeObject(clave);
		out.close();
	} catch (NoSuchAlgorithmException e) {e.printStackTrace();} 
	  catch (FileNotFoundException e) {e.printStackTrace();} 
	  catch (IOException e) {e.printStackTrace();}
   }//main
}//..AlmacenaClaveSecreta

Utilizar la clave secreta almacenada en un fichero para cifrar un documento PDF de nombre FICHERO.pdf

import java.io.*;
import java.security.*;
import javax.crypto.*;

public class Ejemplo13Cifra {
	public static void main(String[] args) {
		try {	
			//RECUPERAMOS CLAVE SECRETA DEL FICHERO
			ObjectInputStream oin = new ObjectInputStream(
					 new FileInputStream("Clave.secreta"));
	        Key clavesecreta = (Key) oin.readObject();
	        oin.close();	        
			//SE DEFINE EL OBJETO Cipher
			Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding");
			c.init(Cipher.ENCRYPT_MODE, clavesecreta);
			//FICHERO A CIFRAR
			FileInputStream filein = new FileInputStream("FICHERO.pdf");
			
			//OBJETO CipherOutputStream
			CipherOutputStream out = new CipherOutputStream(
					new FileOutputStream("FicheroPDF.Cifrado"), c);
			int tambloque = c.getBlockSize();
			byte[] bytes = new byte[tambloque];
			
			//LEEMOS BLOQUES DE BYTES DEL FICHERO PDF 
			//Y LO VAMOS ESCRIBIENDO AL CipherOutputStream
			int i = filein.read(bytes);		
			while (i != -1) {				
				out.write(bytes, 0, i);
				i = filein.read(bytes);
			}
			out.flush();
			out.close();
			filein.close(); 
			System.out.println("Fichero cifrado con clave secreta.");		
						
		} catch (Exception e) {
			e.printStackTrace();
		}
	}//main
}//.. Ejemplo13Cifra

Leer y descifrar datos de un fichero cifrado

import java.io.*;
import java.security.*;
import javax.crypto.*;
public class Ejemplo13Descifra {
	public static void main(String[] args) {
		try {
			//RECUPERAMOS CLAVE SECRETA DEL FICHERO
			ObjectInputStream oin = new ObjectInputStream(
					 new FileInputStream("Clave.secreta"));
	        Key clavesecreta = (Key) oin.readObject();
	        oin.close();	
	        //			
			Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding");
			c.init(Cipher.DECRYPT_MODE, clavesecreta);
			
			CipherInputStream in = new CipherInputStream(
			      new FileInputStream("FicheroPDF.Cifrado"), c);
			
			int tambloque = c.getBlockSize();
			byte[] bytes = new byte[tambloque];
			
			int i = in.read(bytes);		
			FileOutputStream fileout = new FileOutputStream("FICHEROdescifrado.pdf");
		
			while (i != -1)	{
			  fileout.write(bytes, 0, i);
			  i = in.read(bytes);	
			}		
			fileout.close();
			in.close(); 
			System.out.println("Fichero descifrado con clave secreta.");		
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}//main
}//.. Ejemplo13Descifra