Hola, quería reportaros una situación extraña que nos ha ocurrido en el IE7 por 
si lo queréis tener en cuenta para futuras ampliaciones.

 

Estamos usando tarjetas criptográficas con certificado. Por alguna extraña 
razón, se ha quedado alojado en el keystore del navegador uno de los 
certificados de una tarjeta criptográfica, de un sujeto B. El usuario A usa 
otra tarjeta con sus certificados, y cuando accede a la lista se ve el 
certificado del usuario B. Cuando intentamos acceder a la carpeta ciudadana del 
Ayuntamiento de Alicante con el certificado de B no permite la entrada. 
Entonces A entra con su certificado poniendo el pin de su tarjeta. Accede a a 
la aplicación de registro telemático, donde se firmará la instancia con el 
CryptoApplet. A elige el certificado de B para firmar, y le pide el pin de la 
tarjeta criptográfica. A pone el pin de su tarjeta (no tiene la tarjeta de B) y 
el applet dice que el documento PDF se ha firmado correctamente. La instancia 
se guarda en la base de datos. Accedemos a la instancia almacenada en la BD. 
Abrimos el documento pdf y la validación dice que la firma no es correcta., 
Esto ocurre porque la firma se ha cifrado con la clave privada de A y se ha 
agregado al PDF la identidad de B con su clave pública. Por lo tanto, se ha 
guardado en la base de datos una instancia inconsistente.

 

Nosotros hemos solucionado este problema firmando un byte y verificándolo con 
clave pública mediante un objeto Signatura rsa, rsa.sign(data) y 
rsa.verify(data) antes de invocar al objeto Signer en el método run del 
SignatureThread. Así conseguimos que sirva para cualquier tipo de firma.  Es 
importante resaltar que la verificación no funciona bien si usamos directamente 
la clave privada que nos devuelve kAux.getKey(alias) ya que el formato que 
devuelve para la PrivKey no es compatible con el que espera el objeto rsa. Esto 
podemos solucionarlo accediendo directamente al keyStore de Windows. Así ya 
podemos hacer la verificación. Sin embargo, si pasamos esta clave al método 
formatSignature, dará una excepción al invocar al sellado de tiempo, diciendo 
que ese formato no se soporta para este tipo de clave. Por lo tanto, en la 
llamada a formatSignature pasaremos la clave privada que devuelve el método 
kAux.getKey(alias) y el problema se soluciona.

 

Os paso el fragmento con el código:

 

IKeyStoreHelper kAux = xcert.getKeyStore();

 

try {

 

     PrivateKey pk = (PrivateKey) kAux.getKey(xcert

              .getAlias());

 

     X509Certificate cert = xcert.getCertificate();

 

     String alias = "FIRMA";

     PrivateKey privKey = null;

 

     if ((kAux instanceof es.uji.dsign.crypto.keystore.MsCapiKeyStore)) {

         KeyStore ks = KeyStore.getInstance("Windows-MY");

 

         ks.load(null, null);

 

         Enumeration<String> e = ks.aliases();

 

         while (e.hasMoreElements()) {

              String al = e.nextElement();

              if (ks.getCertificate(al).equals(

                        xcert.getCertificate())) {

                   alias = al;

                   privKey = (PrivateKey) ks.getKey(al, null);

                   System.out.println("Clave encontrada");

                   break;

              }

 

         }

         java.security.cert.Certificate cert1 = ks

                   .getCertificate(alias);

 

     } else

         privKey = pk;

     

     java.security.Signature rsa = java.security.Signature

              .getInstance("SHA1withRSA");

     rsa.initSign(privKey);

     rsa.update((byte) 0);

     byte[] res = (rsa.sign());

 

     rsa.initVerify(cert.getPublicKey());

     rsa.update((byte) 0);

     if (rsa.verify(res))

         System.out.println("\nla verificación es correcta");

     else {

         throw new Exception(

                   "\nla verificación NO es correcta");

 

     }

 

 

     sig = signer.formatSignature(in,

              (X509Certificate) cert, pk, kAux.getProvider());

} catch (Exception e) {

     e.printStackTrace();

     System.out.println("Message: " + e.getMessage());

     throw new SignatureAppletException(

              "ERROR_COMPUTING_SIGNATURE");

}

 

if (sig == null) {

     infoLabelField.setText(LabelManager

              .get("ERROR_COMPUTING_SIGNATURE")

              + ": " + signer.getError());

     showSignatureOk = false;

     guiFinalize(false);

     _mw.getAppHandler().getInputParams().flush();

     throw new SignatureAppletException(LabelManager

              .get("ERROR_COMPUTING_SIGNATURE")

              + " :: " + signer.getError(), false);

}

 
_______________________________________________
CryptoApplet mailing list
[email protected]
http://llistes.uji.es/mailman/listinfo/cryptoapplet

Responder a