Técnicas de programación segura con Java
Sumario
Introdución
Java inclúe un conxunto de API que permite garantizar a seguridade de comunicacións, mediante o uso de criptografía e o control de acceso.
Criptografía con JCA
JCA (Java Chriptography Architecture) é unha arquitectura baseada en proveedores que proporciona un conxunto de API para todo o relacionado con criptografía de clave privada e pública:
- Firma dixital
- Hash ou digest de mensaxes
- Certificados dixitais
- Encriptación simétrica e asimétrica
- Xeneración e gestión de claves
- Xeneración de números aleatorios
JCA é unha arquitectura estándar de Java, parte do JDK, que proporciona un marco ou framework no que se integran servizos criptográficos implementados por diferentes proveedores de servizos criptográfifios (ou CSP, cryptographic service provider).
Inclúe paquetes coma:
- java. security
- javax.crypto
- javax.crypto.spec
- javax.crypto.interfaces
Os principios de deseño desta arquitectura son:
- Independencia de implementación. Os servizos de seguridade son proporcionados por proveedores enlazados coa plataforma Java mediante interfaces estándares. Unha aplicación pode utilizar servizos proporcionados por múltiples proveedores independentes.
- Interoperabilidade. Os servicios proporcionados por distintos proveedores son compatibles entre eles. Existen clases que proporcionan un tipo determinado de servizo, e a diferentes algoritmos para este tipo de servizo. Estas se denominan engine classes e son as seguintes:
| Clase | Descripción |
|---|---|
| MessageDigest | Para funcións hash ou digest |
| KeyGenerator | Para xeneración e xestión de claves para criptografía simétrica |
| KeyPairGenerator | Para xeneración e xestión de pares de claves para criptografía asimétrica ou de clave pública |
| Cipher | Para algoritmos de cifrado de datos |
| Signature | Para algoritmos de sinatura dixital |
TAREFA. Obtén os proveedores disponibles no JDK que estés utilizando co método getProviders() da clase Security. Compara cos que aparecen no ficheiro de configuración do JDK, no ficheiro de configuración do JDK conf/security/java.security. Para cada un amosa o seu nome e outra información relevante. Obtén despois todos os servizos proporcionados polo proveedor. Amosa para cada un o seu tipo e o nome do algoritmo. Presta atención os distintos tipos de servizos. Identifica os algoritmos que recoñezas, e localiza algún algoritmo proporcionado por máis dun proveedor.
Explican as capacidades de JCA nos siguientes apartados:
- funcións de hash ou digest
- criptografía de clave simétrica ou privada (comenzando pola xeneración de claves)
- criptografía de clave asimétrica ou de clave pública (comezando pola xeneración de pares de claves)
- certificados dixitais
Resúmenes de mensajes (funcións de hash ou digest)
JCA conten implementacións para os principales algoritmos de hash ou digest. Estos están disponibles mediante a engine classes MessageDigest.
Existen distintos algoritmos de hash: MD5, SHA-1, SHA2 y SHA-3.
NOTA. MD5 e SHA-1 non se consideran seguros na actualidade para criptografía.
Para xenerar un hash con JCA procedese así:
1. Créase un obxecto de clase MessageDigest co método estático getInstance() da mesma clase, especificando o nome do algoritmo. Opcionalmente pódese especificar o nome do proveedor.
2. Engádense datos co método update(). Pódese engadir un byte ou un array de tipo byte[]. Esto se pode facer repetidamente para ir engadindo novos datos.
3. Obtense o valor de hash co método digest().
4. Se quixeramos calcular un novo hash invocaríase ó método reset().
Exemplo
O seguinte programa de exemplo realiza o hash SHA-2 de 256 bits dunha cadea de caracteres introducida como parámetros de líña de comando.
package generacionhash; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class GeneracionHash {
public static void main(String[] args) {
if (args.length < 1) {
System.out.println(
“Introducir cadea de caracteres para calcular hash”);
return;
}
String cadena = args[0];
for(int i=1; i<args.length; i++) {
cadena += “ “+args[i];
}
MessageDigest md;
try {
byte[] bytes = cadena.getBytes();
md = MessageDigest.getInstance(“SHA-256”);
md.update(bytes);
byte[] hash = md.digest();
System.out.printf(“Cadea: [%s]\nHash: [%s]\n.”,
cadena, valorHexadecimal(hash));
} catch (NoSuchAlgorithmException e) {
System.out.println(“Non disponible algoritmo de hash”);
}
}
static String valorHexadecimal(byte[] bytes) {
String result = “”;
for (byte b : bytes) {
result += String.format(String.format(“%x”, b));
}
return result;
}
}
Pódese comparar o resultado co obtido con comandos en linux.
Por exemplo o xeito de obter en Linux o hash SHA-2 de 256 bits para a cadena “Probando cadea” é
$ echo -n “Probando cadea” sha256sum da73486a45ca51ab22c9046b908a8150d21988d6b346f6c67fcd2fb4bc62e8ea
Nota. A opción -n é importante para eliminar o retorno de carro
Tarefa. Probar este programa para a mesma cadea de caracteres e cotexa a súa saída coa de un dos comandos de Linux: md5sum, sha1sum, sha224sum, sha256sum, etc.
Comunicacións seguras con JSSE
Control de acceso con JAAS
JAAS (Java Authentication and Authorization Service, servicio de autorización y autenticación de Java) es una interfaz que pennite a las aplicaciones Java acceder a servicios de control de autenticación y acceso. Pódese utllizar para dous propósitos:
- para a autenticación de usuarios: para detenninar de forma fiable e segura quén está executando o noso código Java
- para a autorización de usuarios: para asegurarse de que quen o executa ten os permisos necesarios para realizar as accións
Están involucradas as seguientes clases e interfaces:
- LoginContext, contexto de inicio de sesión: inicia e xestiona o proceso de autenticación mediante a creación dun Subject.
- A autenticación faise chamando ó método login()
- LoginModule, módulo de conexión: é a interfaz que debe implementarse para definir os mecanismos de autenticación na aplicación. Encárgase de validar os datos nun proceso de autenticación. Debense implementar os seguintes métodos:
- initialize()
- login()
- commit()
- abort()
- logout()
- Subject: clase que representa a un ente autenticable dentro da aplicación (entidade,usuario, sistema)
- Principal: clase que representa os atributos que posee cada Subject recuperado una vez que se efectua o ingreso á aplicación. Un Subject puede contener varios principales.
- CallBackHandler: interfaz que se debe implementar cando se precisa recibir do usuario a información para a autenticación; encárgase da interacción co usuario para obter os datos de autenticación. Débese desarrollar o método handle() para implementala.
As clases e interfaces principais de JAAS están disponibles nos seguintes paquetes:
- javax.security.auth.*: contén as clases de base e interfaces para os mecanismos de autenticación e autorización
- javax.security.auth.callback.*: contén as clases e interfaces para definir as credenciais de autenticación da aplicación
- javax.security.auth.login.*: contén as clases para entrar e sair dun dominio de aplicación
- javax.security.auth.spi.*: contén interfaces para un proveedor de JAAS para implementar módulos JAAS
Autenticación
Autorización
Resumo
- JCA (Java Chriptography Architecure) é unha arquitectura de Java para criptografía.
- JSSE (Java Secure Socket Extension) é unha implementación en Java de TLS/SSL.
- JAAS (Java Authentication and Authorization Service) proporciona
- autenticación de usuarios que executan código de Java
- autorización de usuarios para realizar determinadas accións
Ampliación
- Invesigar o uso de Apache Shiro, Spring Security e OACC como substitutos de JAAS.
Actividades propostas
Xenera o resumo dun ficheiro
O ficheiro débese elixir do disco duro coa clase JFileChooser. O resumo se debe amosar en hexadecimal. Utiliza os algoritmos SHA e MD5 e comproba os resúmenes xenerados
Creación de sockets seguros
Crea unha conexión sobre un socket servidor seguro e que atenderá ata catro conexións de clientes que se identificarán cun certificado válido. O servidor agarda as conexións; cada cliente que se conecta recibe unha mensaxe e a continuación envíalle un saúdo.
Autenticación e autorización
Elabora unha aplicación que nos pida o nome de usuario e contrasinal desde unha ventana de diálogo. A autenticación farase mediante Jaas, onde os usuarios Xosé, Lois e Alba terán acceso. A continuación, haberá dous botóns:
- amosar o número de ficheiros que hai no directorio onde se está executando o programa (poden facelo Xosé, Lois e Alba)
- crear un ficheiro que conteña o nome dos ficheiros que hai no directorio onde se está executando o programa (só pode facelo Xosé)
Referencias e créditos
- Encriptación con Java
- Socket SSL con Java
- JSSE y JAAS
- Java Security Libraries
- Java Cryptography Architecture (JCA) Reference Guide
- Java Secure Socket Extension (JSSE) Reference Guide
- Java Authentication and Authorization Service (JAAS) Reference Guide
- JAAS Exemplo
- Using a CallBackHandler in Java Authentication and Authorization Services (JAAS)