Este documento describe la criptografía en aplicaciones Java. Explica el cálculo de huellas digitales usando la clase MessageDigest y los algoritmos hash. También cubre firmas digitales mediante el uso de claves públicas y privadas, describiendo las clases Signature, Mac, SignedObject y excepciones como SignatureException.
2. Índice
Introducción.
Infraestructura para boletines de mensajes.
Códigos de autenticación de mensajes.
Infraestructura para firmas digitales.
3. Introducción
También conocido como huella digital.
Se calcula aplicando una función hash no
reversible sobre los bits que comprenden el
mensaje.
Cualquier modificación en el mensaje original
resulta en un cambio en valor digest.
Esto hace que sea idóneo para detectar cambios
en el mensaje original. Sin embargo todo esto
se viene abajo si son interceptados a la vez el
mensaje y su valor digest pues se podría
cambiar el mensaje y recalcular su valor.
4. Funciones Hash
Las funciones hash no sirven para asegurar la
confidencialidad, sino para asegurar la
integridad del mensaje, es decir para saber que
el contenido no ha sido alterado por un
atacante.
La función de resumen hash toma un mensaje
de x bits de longitud variable, lo transforma en
otro de h bits de longitud fija h =H(x).
Llamamos huella al mensaje resumido. El caso
ideal seria aquel que cambiando un bit de la
huella del mensaje, supusiere una alteración del
50 por ciento de los bits del mensaje original.
5. Algoritmos de Resumen
MD5: Ron Rivest 1992. Mejoras al MD4 y MD2
(1990), es más lento pero con mayor nivel de
seguridad. Resumen de 128 bits.
SHA-1: Del NIST, National Institute of
Standards and Technology, 1994. Similar a MD5
pero con resumen de 160 bits. Existen otras
propuestas conocidas como SHA-256 y
SHA-512, posibles estándares.
RIPEMD: Comunidad Europea, RACE, 1992.
Resumen de 160 bits.
N-Hash: Nippon Telephone and Telegraph,
1990. Resumen: 128 bits.
6. Algoritmos de Resumen
JDK1.4 nos ofrece los siguientes algoritmos de
resumen:
MD2 y MD5 (que son algoritmos de 128-bits )
SHA-1 (160-bit )
SHA-256, SHA-383, y SHA-512, ( 256, 383, y 512
bits, respectivamente)
Lo mas común es usar MD5 o SHA1.
La clase MessageDigest maneja el resumen de
los mensajes.
7. Infraestructura para boletines de mensaje
Clases e interfaces de boletines de mensajes.
MessageDigest.
Cálculo de boletines de mensajes.
DigestInputStream y DigestOutputStream.
Manejo de flujos de boletín.
DigestException.
8. Clase MessageDigest
La clase MessageDigest fue diseñada para ser
una clase engine que proporcionara servicios
criptográficos asociados a algoritmos de
resumen.
Se utilizan para generar identificadores de datos
únicos y fiables.
Se deben conocer las siguientes fases:
Creación.
Cargar datos.
Cálculo de la huella.
9. Clase MessageDigest
El primer paso para manejar estos elementos es
la creación.
static MessageDigest getInstance(String algorithm).
Se tienen otras posibilidades:
static MessageDigest getInstance(String algorithm, String
provider).
static MessageDigest getInstance(String algorithm,
Provider provider).
Cualquiera de estos métodos devuelve un objeto
MessageDigest inicializado.
10. Clase MessageDigest
El segundo paso para calcular la huella de unos
datos es proporcionar los datos.
Método update:
Cabeceras:
void update(byte input)
void update(byte[] input)
void update(byte[] input, int offset, int len)
11. Clase MessageDigest
Una vez que los datos han sido cargados
mediante el uso del método update, sólo hay
que invocar al método digest:
Cabeceras:
byte[] digest()
byte[] digest(byte[] input)
int digest(byte[] buf, int offset, int len)
Esto implica el cálculo de la huella.
12. DigestInputStream y DigestOutputStream
Simplifican el cálculo de boletines de mensaje
en secuencias de bytes que se leen o escriben
en flujos.
La clase DigestInputStream se utiliza para
calcular un boletín de mensajes en una
secuencia de bytes que se lee a partir de un
flujo.
La clase DigestOutputStream se utiliza para
calcular un boletín de mensajes en una
secuencia de bytes que se escribe un flujo.
Análisis de sus constructores.
13. DigestException
Se utiliza para indicar que se ha producido una
excepción durante el cálculo de un boletín de
mensajes.
El método digest() lanza esta excepción si se
produce algún error.
15. Introducción
La validación de identificación (autenticidad) de
muchos documentos legales, financieros y de
otros tipos se determina por la presencia/
ausencia de una firma manuscrita autorizada o
una firma digital.
La firma digital permite enviar un mensaje
“firmado” a otra parte, con las propiedades de
autenticación (validación identificación),
integridad y no repudio.
LA CLAVE DE LA FIRMA DIGITAL ESTRIBA EN
PEDIR OBLIGATORIAMENTE UN ACUSE DE
RECIBO.
16. Introducción
Se necesita un mecanismo para identificar de
alguna forma el emisor de una determinada
información.
Además, el mecanismo de integridad
proporcionado por las huellas digitales tiene
problemas en cuanto la huella y el mensaje son
interceptados a la vez.
Para solucionar este problema aparecen:
Códigos de autenticación de mensaje.
Firma digital.
18. Introducción
Ejemplo:
Local Remoto
Clave simétrica
Mensaje a mandar Mensaje compartida
recibido
Pay to Terry Smith $100.00 Clave simétrica Pay to Terry Smith $100.00
One Hundred and xx/100 Dollars
compartida One Hundred and xx/100 Dollars
1
Función Función
Hash Hash
Pay to Terry Smith $100.00
One Hundred and xx/100 Dollars 2
4ehIDx67NMop9 4ehIDx67NMop9 4ehIDx67NMop9
Mensaje + Hash
19. Códigos de autenticación de mensajes
Las firmas digitales que se computan a través
de clave secreta se denominan códigos de
autenticación de mensajes.
Es necesario que haya un protocolo de
distribución para clave segura con el fin de
distribuir la clave que está compartida.
20. Códigos de autenticación de mensajes
Ejemplo:
Algoritmo HMAC.
Hash Message Authentication Code.
Consiste en añadir al final del mensaje, el compendio
o resumen de éste, pero cifrado con una clave que
identifica al usuario.
21. Códigos de autenticación de mensajes
Message Authentication Code MAC y Hash MAC
(HMAC) son métodos de autenticación basado
en clave simétrica compartida entre ambas
partes.
Cuando el emisor necesita autenticarse, añade al
mensaje a mandar la clave secreta y lo pasa a través
de la función Hash obteniendo así una huella digital.
Posteriormente envía el mensaje y la huella.
Cuando el receptor recibe el mensaje, genera una
huella digital con el mensaje y la clave secreta que
también conoce.
Compara huellas digitales.
22. Clase Mac
Clase principal que se usa en el cálculo de Mac.
Da soporte a dos algoritmos:
HMAC-MD5: cadena para identificarlo “HmacMD5”.
HMAC-SHA1: cadena para identificarlo “HmacSHA1”.
Al igual que toda clase engine, tiene un método
getInstance que permite obtener una instancia
de dicho objeto.
23. Clase Mac
Métodos auxiliares:
public final void init(Key key)
... y todos los métodos sobrecargados.
public final void update(byte input)
... y todos los métodos sobrecargados.
public final byte[] doFinal(byte[] input)
... y todos los métodos sobrecargados.
24. Firma digital
Introducción.
Clase Signature.
Crear y verificar firmas digitales.
SignedObject.
SignatureException.
25. Firma digital
Un problema estructural del uso de la
criptografía de clave secreta para las firmas
digitales es que todos tienen que confiar en una
autoridad X.
Además, X lee todos los mensajes firmados, por
ello, los candidatos más lógicos para operar el
servidor X son el gobierno, los bancos, ...
Pero estas organizaciones no tiene porqué
inspirar confianza completa a todos los
ciudadanos
26. Firma digital
ECDSA (Elliptic Curve Digital Signature
Algorithm): mecanismo de autenticación para
TLS.
MD2withRSA: este algoritmo usa el algoritmo
de huella digital MD2 y el algoritmo de
encriptación asimétrica RSA para crear y
verificar la firma digital.
MD5withRSA: este algoritmo usa el algoritmo
de huella digital MD5 y el algoritmo de
encriptación asimétrica RSA para crear y
verificar la firma digital.
27. Firma digital
SHA1withDSA: este algoritmo usa el algoritmo
de huella digital SHA-1 y el algoritmo de
encriptación asimétrica DSA para crear y
verificar la firma digital.
28. Firma digital
SHA1withRSA: este algoritmo usa el algoritmo
de huella digital SHA-1 y el algoritmo de
encriptación asimétrica RSA para crear y
verificar la firma digital.
29. Clase Signature
Es una clase engine diseñada para proporcionar
la funcionalidad de un algoritmo de firma
digital.
Una algoritmo de firma segura toma una
entrada de tamaño arbitrario y una clave
privada y genera un conjunto de bytes
relativamente corto llamado firma, con las
siguientes propiedades:
Dada una clave pública correspondiente a la clave
privada usada para generar la firma, es posible
verificar la autenticidad e integridad de la entrada.
La firma y la clave pública no revelan nada sobre la
clave privada.
30. Clase Signature
Estado:
Los objetos Signature siempre tienen un estado.
Estos estados son representados por constantes de
tipo entero. Los posibles estados son:
UNINITIALIZED.
SIGN.
VERIFY.
Cuando un objeto es creado por primera vez su estado
es UNINITIALIZED.
Para cambiar de estado se utilizan los métodos
initSign y initVerify.
31. Clase Signature
Creación de un objeto:
La forma de obtener una instancia de la clase
Signature es mediante el uso de un método
getInstance().
Cabeceras:
static Signature getInstance(String algorithm).
static Signature getInstance(String algorithm, String
provider).
static Signature getInstance(String algorithm,
Provider provider).
32. Clase Signature
Inicialización de un objeto:
Todo objeto debe ser inicializado antes de ser
utilizado.
El método de inicialización depende de si dicho objeto
va a ser utilizado para firmar o verificar.
Si va a ser utilizado para firmar el objeto debe ser
inicializado con una clave privada:
final void initSign(PrivateKey privateKey).
Estado SIGN.
Si va a ser utilizado para verificación el objeto debe
ser inicializado con una clave pública:
final void initVerify(PublicKey publicKey).
Estado VERIFY.
33. Clase Signature
Firmado de un objeto:
El objeto ha sido inicializado a estado SIGN.
Los datos que van a ser firmados deben ser
proporcionado. Esto se realiza mediante una o más
llamadas al método update.
Cabeceras:
final void update(byte b)
final void update(byte[] data)
final void update(byte[] data, int off, int len)
Para generar la firma hay que invocar al método sign:
final byte[] sign()
final int sign(byte[] outbuf, int offset, int len)
34. Clase Signature
Verificación de firma:
El objeto ha sido inicializado a estado VERIFY.
Los datos que van a ser verificados deben ser
proporcionado. Esto se realiza mediante una o más
llamadas al método update.
Cabeceras:
final void update(byte b)
final void update(byte[] data)
final void update(byte[] data, int off, int len)
Para verificar los datos hay que invocar al método
verify:
final boolean verify(byte[] signature)
final boolean verify(byte[] signature, int offset, int
length)
35. Esquema Básico
Creamos una clave
KeyPairGenerator.getInstance("RSA")
initialize(1024)
generateKeyPair()
Creamos una firma del objeto y la inicializamos
Cipher.getInstance("MD5WithRSA")
initSign(clave.getPrivate())
Calculamos la firma a partir del un texto plano y
firmamos
update(textoPlano)
sign()
Configuramos la verificación y verificamos la firma
initVerify(clave.getPublic())
verify(signature)
36. Clase SignedObject
Ofrece la posibilidad de crear objetos firmados
cuya integridad puede ser verificada.
Proporciona una copia de un objeto Serializable
y una firma de la forma serializada del objeto.
La firma se crea a partir de un objeto Signature
y una clave privada que se proporciona al
constructor de la clase.
37. Clase SignedObject
Creación del objeto:
Constructor con parámetros.
Verificación de la firma:
public boolean verify(PublicKey verificationKey
Signature verificationEngine)
Obtención del objeto inicial:
public Object getObject()
38. SignatureException
Se utiliza para representar excepciones que se
producen durante la generación y verificación
de la firma.