Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package facturatron.facturacion.PAC.finkok; import java.io.IOException; import java.io.InputStream; import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import mx.bigdata.sat.exceptions.KeyException; import org.apache.commons.ssl.PKCS8Key; import com.google.common.io.ByteStreams; public final class ClassicKeyLoader { /** * @param crtInputStream Flujo de entrada del certificado del cual se obtiene la llave privada * @param passwd Contrasea con la cual se puede obtener la informacin de la llave * privada * * @return Llave privada encapsulada en el objeto {@link PrivateKey} * * @throws KeyException Lanzada si existe un problema con la lectura de la llave privada. La * excepcin es lanzada si alguno de estos casos se presenta: * <ul> * <li> * Error de lectura del flujo de entrada del documento. * </li> * <li> * Error en la obtencn de la informacin de la llave privada debido * a que la contrasea no es correcta. * </li> * <li> * Error en la obtencin de la llave privada debido a que el algoritmo * de cifrado no es el adecuado para el certificado. * </li> * </ul> */ public static PrivateKey loadPKCS8PrivateKey(InputStream crtInputStream, String passwd) throws KeyException { byte[] decrypted = null; PrivateKey privateKey = null; try { decrypted = (passwd != null) ? getCertBytes(crtInputStream, passwd.toCharArray()) : getBytes(crtInputStream); } catch (IOException ioe) { throw new KeyException("Error de E/S al leer la informacin del certificado", ioe.getCause()); } PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec(decrypted); try { KeyFactory kf = KeyFactory.getInstance("RSA"); privateKey = kf.generatePrivate(keysp); } catch (GeneralSecurityException gse) { throw new KeyException("Error al obtener la informacin del certificado debido a su codificacin", gse.getCause()); } return privateKey; } /** * @param crtInputStream Flujo de entrada del archivo que representa la llave pblica codificada * en x509 * * @return Informacin de la llave pblica encapsulada en el objeto {@link X509Certificate} * * @throws KeyException Lanzada si la codificacin del certificado no es correcta. */ public static X509Certificate loadX509Certificate(InputStream crtInputStream) throws KeyException { CertificateFactory factory = null; X509Certificate x509Crt = null; try { factory = CertificateFactory.getInstance("X.509"); x509Crt = (X509Certificate) factory.generateCertificate(crtInputStream); } catch (CertificateException e) { throw new KeyException("Error al obtener el certificado x.509. La codificacin puede ser incorrecta.", e.getCause()); } return x509Crt; } private static byte[] getBytes(InputStream in) throws IOException { try { return ByteStreams.toByteArray(in); } finally { in.close(); } } private static byte[] getCertBytes(InputStream in, char[] passwd) throws KeyException, IOException { byte[] bytes = null; try { PKCS8Key pkcs8 = new PKCS8Key(in, passwd); bytes = pkcs8.getDecryptedBytes(); } catch (GeneralSecurityException e) { throw new KeyException("La contrasea del certificado no es correcta", e.getCause()); } finally { in.close(); } return bytes; } }