miércoles, 1 de diciembre de 2010

Descripción básica de los modulos

Explicación general de los distintos paquetes en orden de compilación, mencion especial a paquetesUtilidades (el último) que tiene utilidades para el desarrollador

paquetesutil

Utilidades no visuales, Coleccion elementos, lector xml sencillo, ... 

paquetesGUIxSeguridad

Utilidades para leer certificados de Internet Explorer, eDNI, firmar y verificar firma de forma sencilla.

documentación

paquetesutilx

Utilidades no visuales avanzadas, ejecucion de exe, criptografia, ...

paquetes

Modelo de datos, contiene JListDatos, JSelect, IServerServidorDatos, y todos los elementos basicos del modelo datos  Estructura en gráfico


paquetesBD

Conexion con Base datos, utilidades de Base datos, como lector de estructuras

paquetesGUI

utilidades graficas en formato awt

paquetesLogicaDifusa

Contiene el filtro basado en logica difusa (mas o menos)

paquetesGUIx

utilidades graficas en formato Swing, seguridad, plugin, ...

paquetesSincro

Utilidades para sincronizar bases de datos heterogeneas

paquetesEjecutar

Comandos en formato xml, se usa para copiar archivos de http/ftp/carpetas y ejecucion de aplicaciones, este va dirigido por un fichero xml y un metodo factory method (le pasas una cadena y te instancia una clase en funcion de la cadena pasada), solo hay q reimplementar el factory method para incluir mas acciones.
El xml se divide en 2 basicamente, fuentes (origenes de archivos, pueden ser arch. locales, http, ftp, ...,  solo se tiene q implementar el interfaz IFuente) y ejecuciones (copiar archivos desde fuentes, ejecutar aplicaciones,..., interfaz IEjecutarInstruccion)

paquetesArchivosWEB

Protocolo para intercambio de archivos (por paquetes) via http, cada paquete de este protocolo va comprimido (q seguramente es por lo q va mejor q por ftp), hay un interfaz para controlar un sist. de archivos, luego implemente ese interfaz tanto en un sist. de archivos local como un sist. archivos remoto.
Para ello tengo unos servlets en paquetesArchivosWeb

paquetesGUIxAplicacion

Aplicacion base, formulario principal, cargador de plugin, y elementos comunes a todos los proyectos


paquetesImpresionJasper

Utilidades de impresion con JasperReport

paquetesLex

Parse Lexico

paquetesGeneradorInformes

Generador de informes tipo access

paquetesChart

Utilidades para generar graficos a traves de JFreeReport


paquetesArchivosWeb

Intercambio de archivos a traves de la WEB

paquetesImpresionXML

Utilidades de impresion en formato XML sencillo

paquetesImpresionVarios

Utilidades extras de impresion

paquetesImpresionXSLFO

Utilidades de impresion con XSL-FO

paquetesFortram

Utilidades para llamar a programsa fortram

paquetesUtilidades

Utilidades para generar código a partir de la estructura de base datos, comparador de bases de datos heterogeneas, ...

Certificados digitales

1. Firma "en bruto" con eDNI o con cualquier certificado incluido en internet explorer
2. Tomcat pida a internet explorer cliente un certificado digital eDNI
3. Acceso HTTPS con eDNI (DNI electrónico)

1. Firma "en bruto" con eDNI o con cualquier certificado incluido en internet explorer

1.1 mityc

(http://oficinavirtual.mityc.es/componentes/index.html)
Conjunto de clases y dll que ha desarrollado el ministerio de industria para la eFactura
Código:
  • Version 1.0.4
        IESignEngine moBrige = new IESignEngine();
        IPKStoreManager moStore = new IExplorerStore();
        Vector loVector1 = new Vector(moStore.getSignCertificates());
        moBrige.setBinaryCertificate(((X509Certificate) loVector1.get(0)).getEncoded());
        moBrige.setToSign("pepe".getBytes());
        byte[] lab1 = moBrige.engineSign();
        BASE64Encoder moBase64Encoder = new BASE64Encoder();
        BASE64Decoder moBase64Decoder = new BASE64Decoder();       
        System.out.println(moBase64Encoder.encode(lab1));
       
        Signature rsa_vfy = Signature.getInstance("SHA1withRSA");
        rsa_vfy.initVerify(((X509Certificate) loVector1.get(0)).getPublicKey());
        rsa_vfy.update("pepe".getBytes());

        boolean lbResult = rsa_vfy.verify(lab1);
       
        System.out.println("    La verificación resultó:  " + lbResult + "!!!\n");

  • Version 0.9
        // Accedemos al almacén de certificados de internet explorer
        InterfazFirma si = UtilidadFirmaElectronica.getSignatureInstance(EnumAlmacenCertificados.ALMACEN_EXPLORER);

        listCertificates = si.getAllCertificates("My");

        // Accedemos al almacén de certificados de Mozilla Firefox
        //InterfazFirma si = UtilidadFirmaElectronica.getSignatureInstance(EnumAlmacenCertificados.ALMACEN_MOZILLA);
        //listCertificates = si.getAllCertificates("Poner aqui la ruta al perfil de Mozilla");

        System.out.println("Hay " + listCertificates.size() + " certificados");
//        mostrarInformacionCertificados(listCertificates);
        //recogemos el certificado para firmar
//        moCerts = (X509Certificate[]) listCertificates.toArray();
        //Seleccionamos el primero de los certificados para firmar
        moX509 = (X509Certificate) listCertificates.get(0);
//        // Consigue la clave privada
//        moPriv = (PrivateKey) keystore.getKey(alias, pwd);
//
//        if (moPriv == null) {
//            throw new Exception(alias + " could not be accessed");
//        }
        byte[] labDatos = "perico de los palotes".getBytes();
        FirmaMSBridge loBrige = new FirmaMSBridge();
        loBrige.setBinaryCertificate(moX509.getSignature());
        loBrige.setToSign(labDatos);
        loBrige.engineSetParameter(
                ParametrosFirma.getInstance(
                    moX509.getSerialNumber(),
                    moX509.getIssuerDN().toString()));
        byte[] labFirma = loBrige.engineSign();


        System.out.println();
        System.out.println(new String(labFirma));
        System.out.println();

        BASE64Encoder base64Encoder = new BASE64Encoder();
        String lsFirmaBase64 = base64Encoder.encode(labFirma);

        System.out.println();
        System.out.println(lsFirmaBase64);
        System.out.println();

        BASE64Decoder base64Decoder = new BASE64Decoder();
        byte[] b= base64Decoder.decodeBuffer(lsFirmaBase64);
        byte[] datos= labDatos;

        //Verification:
        System.out.println("    Verificando la firma ...");
        Signature rsa_vfy = Signature.getInstance( "SHA1withRSA");
        rsa_vfy.initVerify(moX509.getPublicKey());
        rsa_vfy.update(datos);
        System.out.println("    La verificación resultó:  " + rsa_vfy.verify(b) + "!!!\n");

 

1.2 SunMSCAPI

Conjunto de clases y dll incorporadas en jre 1.6
KeyStore ks = KeyStore.getInstance("Windows-MY");
        // Note: When a security manager is installed, 
        // the following call requires SecurityPermission 
        // "authProvider.SunMSCAPI".
        ks.load(null, null); 

        byte[] data = ...
        String alias = "myRSA";

        PrivateKey privKey = (PrivateKey) ks.getKey(alias, null);
        Certificate cert = ks.getCertificate(alias);

        Provider p = ks.getProvider();
        Signature sig = Signature.getInstance("SHA1withRSA", p);
        sig.initSign(privKey);
        sig.update(data);
        byte[] signature = sig.sign();
        System.out.println("\tGenerated signature...");
        sig.initVerify(cert);
        sig.update(data);
        if (sig.verify(signature)) {
           System.out.println("\tSignature verified!");
        } 

2. Tomcat pida a internet explorer cliente un certificado digital eDNI


descomentar las lineas
    <!--
    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" />
    -->

y dejarla asi

    <Connector port="8443" maxHttpHeaderSize="8192"  SSLEnabled="true"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
          acceptCount="100" scheme="https" secure="true"
        enableLookups="false" disableUploadTimeout="true"
               clientAuth="true" sslProtocol="TLS"
               truststoreFile="/home/eduardo/.truststore" truststorePass="eduardo"
            keystoreFile="/home/eduardo/myKeyStore" keystorePass="eduardo"
   />

Los parámetros de configuración del elemento "Connector" que debemos establecer son:
  1. clientAuth: true-> es el que pedira el certificado al cliente
  2. TruststoreFile: el certificado que cumpla la cadena de confianza podra ser seleccionado por el  cliente, "pá" enterdernos,  en el internet explorer solo aparareceran para seleccionar los certificados que cumplan la cadena de confianza de este archivo
  3. truststorePass: password del fichero anterior
  4. keystoreFile: el almacen de nuestro certificado digital en el servidor
  5. keystorePass: password del fichero anterior
keytool -v -keystore /home/eduardo/myKeyStore -genkey -keyalg rsa   

El keytool nos pedirá una contraseña: "eduardo". Después nos pedirá una serie de datos para el certificado:
Importante: en la pregunta¿Cuáles son su nombre y su apellido? poner la ip o dns de la pagina web, pq asi en el navegador de internet explorer puedes añadir el certificado a entidades emisoras raiz de confianza y asi NO te hace la pregunta de q "no es un certificado de confianza" O usar un certificado firmado por fnmt o @firma o firma profesional

Escriba la contraseña del almacén de claves: 
Volver a escribir la contraseña nueva:
¿Cuáles son su nombre y su apellido?
  [Unknown]:  172.16.0.4
¿Cuál es el nombre de su unidad de organización?
  [Unknown]:  Informatica
¿Cuál es el nombre de su organización?
  [Unknown]:  informatica
¿Cuál es el nombre de su ciudad o localidad?
  [Unknown]:  Murcia
¿Cuál es el nombre de su estado o provincia?
  [Unknown]:  Murcia
¿Cuál es el código de país de dos letras de la unidad?
  [Unknown]:  es
¿Es correcto CN=Eduardo Gonzalez, OU=Informatica, O=informatica, L=Murcia, ST=Murcia, C=es?
  [no]:  y

Generando par de claves RSA de 1.024 bits para certificado autofirmado (SHA1withRSA) con una validez de 90 días
    para: CN=Eduardo Gonzalez, OU=Informatica, O=informatica, L=Murcia, ST=Murcia, C=es
Escriba la contraseña clave para <mykey>
    (INTRO si es la misma contraseña que la del almacén de claves): 

Le damos a INTRO para que utilice la misma que la del almacén.
Bajarse el certificado raiz de eDNI http://www.cert.fnmt.es/index.php?cha=cit&sec=4&page=139&lang=es
 keytool -import -keystore /home/eduardo/.truststore -file FNMTClase2CA.cer 
    • Import the Chain Certificate into you keystore
      keytool -import -alias root -keystore <your_keystore_filename> \
       -trustcacerts -file <filename_of_the_chain_certificate>
    • And finally import your new Certificate
      keytool -import -alias tomcat -keystore <your_keystore_filename> \
       -trustcacerts -file <your_certificate_filename>

  • Prueba de que va todo bien:en internet explorer poner https://localhost:8443 y debe pedir el certificado digital eDNI
  • Configurar una aplicacion para forzar las comunicaciones como https
En el WEB-INF/web.xml de la aplicacion:

<security-constraint>
  <web-resource-collection>
    <web-resource-name>Entire  Application</web-resource-name>
    <url-pattern>*.ctrl</url-pattern>
    <url-pattern>*.jsp</url-pattern>
  </web-resource-collection>
  <user-data-constraint>
    <transport-guarantee>CONFIDENTIAL</transport-guarantee>
  </user-data-constraint>
</security-constraint>

esto es todas las paginas con .ctrl o .jsp se pedira propotoco seguro y el certificado digital eDNI

otro ejemplo

<security-constraint>
  <web-resource-collection>
    <web-resource-name>Entire  Application</web-resource-name>
  <url-pattern>/secure/*</url-pattern>  
</web-resource-collection>

  <user-data-constraint>
    <transport-guarantee>CONFIDENTIAL</transport-guarantee>
  </user-data-constraint>
</security-constraint>

Todas las llamadas q esten en el directorio /secure de la aplicacion
  • para obtener los datos del certificado del cliente en un servlet del servidor:

X509Certificate[] certs;
certs = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
if (certs != null) {
    clientCert = certs[0];
}

3. Acceso HTTPS con eDNI (DNI electrónico)



Para acceder a una página web mediante protocolo https con eDNI ver paquetesGUIxSeguridad

paquetesGUIxSeguridad

Utilidades para leer certificados de Internet Explorer, eDNI, firmar y verificar firma de forma sencilla.
1. Acceso HTTPS con eDNI
2. Firma digital y verificación
3. Seleccionar un certificado de forma visual


1. Acceso HTTPS con eDNI



import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.security.KeyStore;
import java.security.Provider;
import java.security.Security;
import java.util.Enumeration;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import utilesGUIxSeguridad.JCertificadosSUN;
import utilesGUIxSeguridad.JFrameSeleccionarCertificado;

/**
 *
 * @author eduardo
 */
public class JTest5 {

    public static void main(String[] args) throws Exception {
        //conectamos con url
        HttpsURLConnection connection = null;
        URL url = null;
        //config. para leer la dll PKCS11 directamente (en este caso la de la Universidad de Murcia)
        String ls =
                "name = DNIe" + "\n"
                + "slot = 1" + "\n"
                + "library = c:/WINDOWS/system32/UMU_PKCS11_v1_02.dll" + "\n"
                + "showInfo=true" + "\n";
        InputStream loConf = new ByteArrayInputStream(ls.getBytes());
        //Creamos el Provider con la clase SunPKCS11
        Provider nss = new sun.security.pkcs11.SunPKCS11(loConf);
        Security.addProvider(nss);
        //creamos el keystore
        KeyStore ks = KeyStore.getInstance("PKCS11", nss);
        ks.load(null, "1111".toCharArray());
        //recorremos todos los certificados e imprimimos el titulo
        Enumeration aliases = ks.aliases();
        String alias = null;
        while (aliases.hasMoreElements()) {
            alias = (String) aliases.nextElement();
            System.out.println(alias);
        }

        //creamos el controlador de seguridad
        JCertificadosSUN loCert = new JCertificadosSUN();
        //establecemos el keystore
        loCert.setKeyStore(ks);
        //seleccionamos un certificado
        new JFrameSeleccionarCertificado(null, loCert).setVisible(true);

        SSLContext sc = SSLContext.getInstance("SSLv3");

        url = new URL("https://172.16.0.4:8443/");

        connection = (HttpsURLConnection) url.openConnection();
        //establecemos el verificador de nombres, la funcion de esta clase es comprobar que el certificado del servidor
        //contiene la direccion del servidor, si se construye con true ignora esta comprobacion, util para pruebas
        connection.setHostnameVerifier(new JTramitacionOnLineHostNameVerifier(true));
        //establecemos el conexto ssl, con nuestro controlador de certificados que ya tiene el certificado a usar
        sc.init(
                //controlador de certificados que ya tiene el certificado a usar
                new KeyManager[]{
                    new JTramitacionOnLineKeyManager(loCert)
                },
                //TrustManager:comprueba la cadena de confianza del certificado del servidor
                //cuando se crea a true no comprueba la cadena de confianza del certificado del servidor, es util cuando somos nosotros los q creamos los certificados
                new TrustManager[]{new JTramitacionOnLineTrustManager(true)},
                null);
        connection.setSSLSocketFactory(sc.getSocketFactory());
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        connection.setRequestProperty("User-Agent", "Mozilla/4.05 [en] (WinNT; I)");
        connection.setFollowRedirects(true);
        connection.setInstanceFollowRedirects(true);
        connection.setUseCaches(false);
        connection.setDoInput(true);
        connection.setDoOutput(true);

        OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());

        out.write("");
        out.close();

        System.err.println(connection.getResponseCode());

        InputStream in = connection.getInputStream();
        int l;
        while ((l = in.read()) >= 0) {
            System.out.print((char) l);
        }
    }
}

2. Firma digital y verificación

        ICertificados loAux = new JCertificadosSUN();
        Vector loVector = loAux.getListaCertificados();
        loAux.mostrarInformacionCertificados(loVector);
        loAux.setX509Certificate((X509Certificate) loVector.get(0));
        byte[] lab = loAux.sign("pepe".getBytes());

        System.out.println(loAux.getTransFormarABASE64(lab));

        System.out.println("    La verificación resultó:  " + loAux.verificar("pepe".getBytes(), lab) + "!!!\n");



3. Seleccionar un certificado de forma visual


        try {
            ICertificados loCert = new JCertificadosSUN();
            //mostramos el formulario para seleccionar un certificado digital
            new JFrameSeleccionarCertificado(null, loCert).setVisible(true);
            byte[] lab = loCert.sign("pepe".getBytes());
            System.out.println(loCert.getTransFormarABASE64(lab));
            System.out.println("    La verificación resultó:  " + loCert.verificar("pepe".getBytes(), lab) + "!!!\n");
        } catch (Exception ex) {
            ex.printStackTrace();
            JOptionPane.showMessageDialog(new JLabel(), ex);
        }



Página principal: http://www.creativa3d.com/modeloDatos.html

listDatos

FrameWork para aplicaciones Swing, multibase datos, creación de plug-in sencillos, la fuente de datos puede ser un servidor Tomcat, conjunto de componentes Swing adaptados al FrameWork

Página principal: http://www.creativa3d.com/modeloDatos.html