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 )
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 );
}
}
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)
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