sábado, 24 de abril de 2010

Validar una clave Privada con su Certificado en JAVA

Hola de nuevo, como que esto de escribir en el blog ya me me esta gustando, bueno, solo como complemento de la entrada anterior donde encriptamos un archivo con la llave privada queria escribor como validar un archivo con un certificado.

Para esto lo que se tiene que hacer es crear un objeto X509Certificat a partir un byte[] o un InputStream que contiene el archivo.cer

File archivoCer = new File("c:/certificado.cer");
InputStream fis = new FileInputStream(archivoCer);// Se maneja la excepcion
X509Certificate cert = X509Certificate.getInstance(fis);

A continuacion se crea un objeto Signature pasandole e algoritmo de encripcion, en nuestro caso es el MD5withRSA, este es el mismo objeto que utilizamos para firmar nuestro archivo, pero esta vez lo inicializaremos para verificar nuestro archivo firmado con el certificado que tenemos

Signature firma = Signature.getInstance("MD5withRSA");
firma.initVerify(cert.getPublicKey());

A continuacion le cargamos el archivo o texto sin firmar

firma.update(textoAFirmar.getBytes("UTF-8"));

Y por ultimo verificamos el archivo firmado, donde textoFirmado en un byte[] que obtuvimos despues de firmar un archivo

firma.verify(textoFirmado)

Bueno, espero que les halla servido, yo tuve que utilizar esto para verificar que el certifiado fuera valido con respecto al la clave privada que estaba ingresando, bueno les pego el codigo de toda la clase para que lo entiendan mejor:

package com.infosoft.rasengan.util;

import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.SignatureException;

import javax.security.cert.CertificateException;
import javax.security.cert.X509Certificate;

import org.apache.commons.ssl.PKCS8Key;
import org.apache.commons.ssl.ProbablyNotPKCS8Exception;

public class CertificateValidator {

public final static int SUCCESS = 0;
public final static int ERROR_PASSWORD = 1;
public final static int ERROR_PRIVATE_KEY = 2;
public final static int ERROR_PUBLIC_KEY = 3;
public final static int ERROR_PUBLIC_PRIVATE_KEY = 4;

private byte[] clavePrivada;
private byte[] clavePublica;
private String password;

public CertificateValidator(InputStream archivoClavePrivada,
InputStream archivoClavePublica, String password) {
this.clavePrivada = FormatUtil.getBytes(archivoClavePrivada);
this.clavePublica = FormatUtil.getBytes(archivoClavePublica);
this.password = password;
}

/**
* Valida el certificado digital, la clave privada, asi como su relacion
*
* @return - 0 si todo esta correcto
* - 1 si el password de la clave privada no es correcto
* - 2 si la clave privada no es un archivo que corresponda al estandar PKCS8
* - 3 si el certificado no es un archivo que corresponda al estandar PKCS10
* - 4 si el certificado no corresponde a la clave privada
*/

public int validate() {
String textoAFirmar = "||2.0|FDF|28125|2007-09-12T12:47:31|11160|2007|ingreso|Pago en una sola exhibicion|"
+ "TERMINOS CONTADO ESP|3674.13|4225.25|IMM9304016Z4|Ingram Micro Mexico S.A. de C.V.|Laguna de Terminos|249|"
+ "Anahuac|Miguel Hidalgo|Distrito Federal|Mexico|11320|Av. 16 de Septiembre|225|San MartinXochinahuac|"
+ "Azcapotzalco|Distrito Federal|Mexico|02140|CAOG8406274R0|CHAVEZ OCHOA GABRIEL|HDA. DE CORLOME NO. 51|"
+ "COL. FLORESTA COYOACAN|DELG. TLALPAN|MEXICO, D.F. MX 14310|MX|3.00|"
+ "TONER NEGRO P/LASERJET SUPL 2420 (6,000 PAG )|1189.04|3567.12|1.00|COMISION TARJETA DECREDITO|"
+ "107.01|107.01|IVA|15.00|551.12|551.12||";
try {
PKCS8Key pkcs8 = new PKCS8Key(clavePrivada, password.toCharArray());
PrivateKey pk = pkcs8.getPrivateKey();
Signature firma = Signature.getInstance("MD5withRSA");
firma.initSign(pk);
firma.update(textoAFirmar.getBytes("UTF-8"));
byte[] firmado = firma.sign();
X509Certificate cert = X509Certificate.getInstance(clavePublica);
cert.checkValidity();
firma.initVerify(cert.getPublicKey());
firma.update(textoAFirmar.getBytes("UTF-8"));
if (firma.verify(firmado)) {
return SUCCESS;
} else {
return ERROR_PUBLIC_PRIVATE_KEY;
}
} catch (ProbablyNotPKCS8Exception e) {
return ERROR_PRIVATE_KEY;
} catch (UnsupportedEncodingException e) {
return ERROR_PRIVATE_KEY;
} catch (SignatureException e) {
return ERROR_PRIVATE_KEY;
} catch (GeneralSecurityException e) {
return ERROR_PASSWORD;
} catch (CertificateException e) {
return ERROR_PUBLIC_KEY;
}
}

}

Saludos