Desarrollo de
Aplicaciones Seguras
con Java
Alfredo Barón Ocampo
EAI & SOA Solutions Architect
Parte 1
Agenda
1. Java.
2. Seguridad de la plataforma.
3. Criptografía.
4. Public Key Infrastructure
(PKI).
¿Qué es Java?
• Un conjunto de especificaciones que
definen todas y cada una de las
tecnologías que forman la plataforma.
• Se define el lenguaje, el formato binario de los
bytecodes, la máquina virtual y las librerías
estándar (JDK).
• Hay múltiples implementaciones de las
especificaciones, la más utilizada es la de
SUN.
• Java no es un software.
¿Porqué Java?
►Multiplataforma.
►Es orientado a objetos.
►Fácil de aprender (vs. C o C++).
►Lenguaje por excelencia en internet.
►Riquísimo en librerías, tanto comerciales
como de código abierto.
►Participan muchas empresas,
universidades e individuos en la definición
de las especificaciones.
Plataforma Java
J2SE (Java 2 Standard Edition)
J2EE (Java 2 Enterprise Edition)
J2EE (Java 2 Enterprise Edition)
J2EE (Java 2 Enterprise Edition)
Modos de Uso
• Applets: programas autoejecutables desde
una página web.
• Aplicaciones: Programa standalone.
• Beans: Componentes.
• Servlets: Aplicaciones ejecutadas en
servidor.
• Aglets: Agentes Inteligentes.
• Doclets: Generadores de documentos
configurables.
Seguridad de la Plataforma
Características
• La definición del lenguaje Java y de la
Máquina Virtual de Java (JVM) incluyen
características de seguridad en bajo nivel:
• Tipo de datos bien definido.
• Administración de memoria automática.
• Verificación de los bytecodes.
• Carga de clases de forma segura.
Beneficios
• Proveer de una plataforma segura y con
características de seguridad para el
desarrollo y ejecución de aplicaciones.
• La administración automática de la
memoria y la verificación de los tipos de
datos en la fase de compilación nos lleva a
un código más robusto y reduce la
vulnerabilidad y corrupciones de memoria.
Beneficios
• La verificación de los bytecodes permite
cumplir con la especificación JVM y
previene la ejecución de código hostil
desde un ambiente de ejecución corrupto.
• Los cargadores de clases aseguran que
código no confiable interfiera con la
ejecución de otros programas Java
confiables o no confiables.
Clases
• El archivo de clases define
nombres/tipos/valores de las variables,
constantes y métodos de la misma.
• Los métodos se almacenan como
instrucciones para ejecutarse como una
pila en la JVM.
• Muy similar al UCSD p-code.
JVM
• La JVM ejecuta archivos de clases
(incluyendo colecciones de la misma).
• Por interpretación, compilación en tiempo de
ejecución o cualquier combinación de los
anteriores, el rendimiento es un punto a
considerar.
• La JVM ejecuta un “verificador de
bytecode” para revisar la legalidad de un
archivo de clases.
Compilación y Ejecución
Seguridad Básica
• No a apuntadores arbitrarios: referencia.
• Solo el creador y el creado tienen referencia al
nuevo objeto.
• Si el objectset no pasa una referencia, no se
puede manipular el objeto.
Seguridad Básica
• Solo se pueden manipular los objetos en
forma limitada.
• Si los datos son privados, se pueden
manipular exclusivamente por los métodos.
• Los métodos pueden ser usados para proteger
los datos.
• El método constructor puede limitar quién
puede crear un objeto.
Seguridad Básica
Conclusiones
• Una aplicación java se considera segura
debido a:
• No acceden a zonas delicadas de memoria o de
sistema, con lo cual evitan la interacción de ciertos
virus.
• Java no posee una semántica específica para
modificar la pila de programa o la memoria libre o
utilizar objetos y métodos de un programa sin los
privilegios del kernel del sistema operativo.
• Ningún objeto se crea y almacena en memoria, sin
que se validen los privilegios de acceso, la seguridad
se integra en el momento en que se interpreta, con el
nivel de detalle y de privilegio que sea necesario.
Criptografía
Introducción
• Java provee acceso a funciones
criptográficas a través del framework JCA
(Java Cryptography Architecture), el cuál
fue introducido a partir del JDK 1.1.
• Las adiciones de criptografía fueron
establecidas como extensiones al JCA y se
denominaron JCE (Java Cryptography
Extensions), las cuáles fueron ontegradas
dentro del JDK 1.4.
Servicios Criptográficos
• Se proveen acceso a diferentes servicios
criptográficos:
• Algoritmos de digestión.
• Algoritmos de firma digital.
• Encripciones simétricas.
• Encripciones asimétricas.
• Encripción basada en contraseña (PBE).
• Criptografía de curvas elípticas (ECC).
• Algoritmos de generación de llaves.
• Algoritmos de autenticación de mensajes
(MAC).
• Generadores de números aleatorios.
Usos
• Digestiones (Hash):
• Autenticación de mensajes.
• Validación de documentos electrónicos.
• Encripción (Simetrica / Asimetrica).
• Comunicaciones seguras.
• Almacenamiento seguro.
• Privacidad.
• Firmas Digitales.
• Identidad / Confianza.
• Detección de fraudes.
JCE
• Provee una interfase estándar de acceso a
las funciones criptográficas.
• Usa patrones para proveer una API
consistente para todos los algoritmos.
• Provee una arquitectura de conectividad
(plug-in) que permite la implementación de
terceros..
• Genera proveedores de servicios
criptográficos.
Lista de Proveedores
• Almacenada en:
JAVA_HOME/lib/security/[Link]
• El orden es muy importante.
• El primer proveedor que implemente un
argoritmo se convierte en el default.
• Ejemplo:
[Link].1=[Link]
[Link].2=[Link]
[Link].3=[Link]
[Link].4=[Link]
[Link].5=[Link]
[Link].6=[Link]
[Link].7=[Link]
Flexibilidad
• Al momento de ejecutar un método que
implementa un algoritmo criptográfico, se
puede especificar el proveedor de servicios
que se desea utilizar.
Cipher cipher =
[Link]("DES/ECB/PKCS5Padding","SunJCE");
Algoritmo/Modo/Pad Proveedor (opc))
Más Flexibilidad
• Agregar proveedores dentro del código
para su utilización.
import [Link];
import [Link];
import [Link];
[Link](new BouncyCastleProvider());
Cipher cipher =
[Link]("DES/ECB/PKCS5Padding", "BC");
Información de un Proveedor
import [Link];
import [Link];
import [Link];
...
for(Provider p : [Link]()) {
[Link](”========================");
[Link]("Proveedor: "+ [Link]());
for(Service s : [Link]()) {
[Link]([Link]());
}
}
Números Aleatorios
import [Link];
SecureRandom random = new SecureRandom();
long seed = [Link]() ^
[Link]().freeMemory();
[Link](seed);
byte bytes[] = new byte[20];
[Link](bytes);
//bytes=150526efd293b645e31b1dbba98b600ce38228dc
Digestiones (Hashes)
• Funciones de una sola vía.
• Crean un valor único (estadístico) para una
entrada dada.
• Algoritmos:
–SHA 1/256/512.
–MD5 Å Considerado no seguro (1).
(1) [Link]
Digestiones (Hashes)
try {
MessageDigest md = [Link]("SHA");
byte[] digest = [Link]("Hello World".getBytes());
} catch (NoSuchAlgorithmException nsae) {
}
// digest = 0a4d55a8d778e5022fab701977c5d840bbc486d0
Cifrado Simétrico
• Una llave es compartida entre dos (o mas)
compañeros.
• Cualquiera que tenga la llave puede
desencriptar un mensaje o enviar uno
nuevo encriptado.
• Son más rápidos que los algoritmos
asimétricos.
• Tipos:
• Block - procesa por bloques de bytes.
• Stream – procesa bit por bit.
Cifrado Simétrico
Encripción Æ
Desencripción Æ
Algoritmos Simétricos
• DES
• Date Encryption Standard (desde 1976).
• Llaves de 8 bytes (56 bits + checksum).
• Triple-DES (DES-ede)
• ede = Encrypt - Decrypt – Encrypt
• Llaves 2 DES o 3 DES Keys (más fuertes).
• AES (Rijndael)
• Advanced Encryption Standard.
• Estándar desde el 2001.
• Tamaño de llaves de 128, 192, 256 bits.
Ejemplo de Cifrado Simétrico
byte[] keyMaterial = "my super secret password".getBytes();
String message = "Hello, World!";
SecretKeySpec key = new SecretKeySpec(keyMaterial, "AES");
// encrypting
Cipher cipher = [Link]("AES/ECB/PKCS5Padding");
[Link](Cipher.ENCRYPT_MODE, key );
byte[] plaintext = [Link]("8859_1");
// plaintext = 48656c6c6f2c20576f726c6421
byte[] ciphertext = [Link](plaintext);
// ciphertext = 93a5f36dfbfb518b2f94d61616d4505
// decrypting
[Link](Cipher.DECRYPT_MODE, key);
byte[] plaintext2 = [Link](ciphertext);
// plaintext2 = 48656c6c6f2c20576f726c6421
Encripción Basada en Contraseña
• PBE (Password Based Encryption).
• Usa algoritmos simétricos estándares.
• Combina una contraseña con un “salt” para
formar una llave.
• Solamente es seguro de acuerdo a la
contraseña elegida.
Ejemplo PBE
// PBE con TripleDES
String keyMaterial = "my super secret password";
byte[] salt = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
int iterationCount = 2048;
PBEKeySpec keySpec =
new PBEKeySpec([Link](), salt, iterationCount);
SecretKeyFactory keyFactory =
[Link]("PBEWithSHAAnd3KeyTripleDES", "BC");
Key key = [Link](keySpec);
String message = "Hello, World!";
// encriptando
Cipher cipher = [Link]("PBEWithSHAAnd3KeyTripleDES", "BC");
[Link](Cipher.ENCRYPT_MODE, key );
byte[] plaintext = [Link]("8859_1");
// plaintext = 48656c6c6f2c20576f726c6421
byte[] ciphertext = [Link](plaintext);
// ciphertext = 16c6640f2b7f55cf416be9130b905eca
Cifrado Asimétrico
• Conocida como Criptografía de Llave
Pública.
• Las llaves consisten en dos partes
relacionadas:
• Llave Pública – tipicamente contenida en un
certificado digital.
• Llave Privada – se mantiene en secreto.
• Matemáticamente difícil (pero posible) de
derivar la llave privada de la llave pública.
Cifrado Asimétrico
Creación
Cifrado Asimétrico
Uso
Public Key Infrastructure
(PKI)
¿Qué es PKI?
• El acrónimo PKI deriva de "Public Key
Infrastructure" (Infraestructura de Llave
Pública) y es la forma común de referirse a
un sistema complejo necesario para la
gestión de certificados digitales y
aplicaciones de la Firma Digital.
¿Qué debe cumplir?
• Una PKI bien construida debe proporcionar:
• Autenticidad: la firma digital tendrá la
misma validez que la manuscrita.
• Confidencialidad: de la información
transmitida entre las partes.
• Integridad: debe asegurarse la
capacidad de detectar si un documento
firmado ha sido manipulado.
• No Repudio: de un documento firmado
digitalmente.
Certificados
• Los certificados (Llaves Públicas) forman
una estructura jerárquica de confianza:
• Empiezan con un certificado raíz.
• El cuál confía (firma) certificados de
autoridades (ya sean registradoras o
certificadoras).
• El cuál confía (firma) certificados comunes.
• El certificado común, incluída su jerarquía, se
denomina cadena de certificación.
• La jerarquía es administrada con las listas
de revocados (CRLs).
Almacén de Llaves
• Sirven para almacenar y recuperar llaves y
certificados desde un archivo protegido por
contraseña o desde dispositivos
criptográficos.
• Keytool Å Herramienta del JDK para
administrar almacén de llaves.
• CACerts Å Almacén de certificados raíz.
• JAVA_HOME/lib/security/cacerts
• Almacén por omisión:
• ~/.keystore (Mac/Linux).
• \document and settings\profile\.keystore (Win).
Creación de Llaves
Algoritmo
matemático
Clave
Privada “Privada”
Clave
Pública “Pública”
Creación de Firma Digital
Documento Electrónico
Clave privada firmado (a enviar)
Documento
Algoritmo de
original
Resumen o hash
Firma Documento
digital original
$k%o&R?F!+
MD5 *_e>#A
PRIV
*RSA
12345678 (algoritmo $k%o&R?F
Hash codificación)
90123456 !+*_e>#A
Firma electrónica
Resumen o
hashing
* RSA: Sistema de encripción de llave pública que se aplica para generar firma electrónica.
Validación de Firma Digital
Documento electrónico
firmado (recibido)
Documento
Documento original
original
Firma digital
Algoritmo
$k%o&R?F de resumen
!+*_e>#A Clave de
o hash MD5
verificación del
firmante
PUB
SI
*RSA
$k%o&R?F 12345678 = 12345678
!+*_e>#A 90123456 ? 90123456
Firma electrónica
Resumen NO Resumen
o hashing o hashing
Generación de un Autocertificado
LA FIRMA Y ENSOBRETAMIENTO DIGITAL ASEGURAN LA
CONFIDENCIALIDAD, AUTENTICIDAD E INTEGRIDAD DE LA
INFORMACION
• Documento o Transacción
Iuwdndvksfougyeowf
pmvmjdhguefiokwldx
128 / 160 bits
Usuario mcsjkhgfoewifdkkaef
• Digestión
• Firma Electrónica
• Llave privada usuario
• Sobre Digital
• Llave pública destinatario
• Certificado Destinatario
• Certificado Usuario
Destinatario
Generación de un Autocertificado
~$ keytool -genkey -alias mykey -keyalg RSA -keysize 1024 -keystore
my_keys.store -storetype JCEKS -storepass password
What is your first and last name?
[Unknown]: Common Name
What is the name of your organizational unit?
[Unknown]: OU
What is the name of your organization?
[Unknown]: O
What is the name of your City or Locality?
[Unknown]: L
What is the name of your State or Province?
[Unknown]: S
What is the two-letter country code for this unit?
[Unknown]: US
Is CN=Common Name, OU=OU, O=O, L=L, ST=S, C=US correct?
[no]: yes
Enter key password for <mykey>
(RETURN if same as keystore password):
~$ keytool -selfcert -alias mykey -keystore my_keys.store -storetype JCEKS -
storepass password
~$
Firma Digital
char[] password = "password".toCharArray();
KeyStore ks = [Link]("JCEKS");
FileInputStream fis = new FileInputStream("my_keys.store");
[Link](fis, password);
Key privateKey = [Link]("mykey", password);
X509Certificate cert = (X509Certificate) [Link]("mykey");
[Link]();
byte[] mydata = "Bob, your secret is safe with me".getBytes();
Signature sig = [Link]("SHA1withRSA");
[Link]((PrivateKey) privateKey);
[Link](mydata);
byte[] signature = [Link]();
[Link]("signature: " + toHex(signature));
//6592a835c24d98efa1cda70c179ab9d1b887b4dd0682c3451176fd921e12dab9fa618981
3f22c7a8248654a8d87f356b5565fc952104af04ceb1138e9be3034137944a98262876089e
9875c1ad3f673cb035d9d56a1dc9e359b45dcd8029e69065728072569ce235fa4fec0f9b56
0606bc080e7b5c5af3fb7846f2db600a9732
[Link](cert);
boolean valid = [Link](signature);
[Link]("Valid? " + valid);
¿Preguntas?
Alfredo Barón Ocampo
EAI & SOA Solutions Architect
[Link]@[Link]