import java.io.*; import java.security.*; import java.security.cert.*; import java.util.*; import sun.security.x509.X509CertImpl; import sun.security.x509.X509CertInfo; import sun.security.x509.X500Name; import sun.security.x509.AlgorithmId; import sun.security.x509.CertificateIssuerName; import sun.security.x509.CertificateSubjectName; import sun.security.x509.CertificateValidity; import sun.security.x509.CertificateSerialNumber; import sun.security.x509.CertificateAlgorithmId; public class FirmarCertificado { // Algoritmo usado para firmar el certificado private static final String ALG = "MD5WithRSA"; // Validez del certificado en dias private static final int VALIDEZ = 365; public static void main (String[] args) throws Exception { if (args.length != 4) { System.err.println( "Uso: java FirmarCertificado keystore aliasCA aliasCert aliasNuevo"); System.exit(1); } String fich_keystore = args[0]; String aliasCA = args[1]; String aliasCert = args[2]; String aliasNuevo = args[3]; // Obtener los passwords BufferedReader in = new BufferedReader (new InputStreamReader(System.in)); System.out.print("Password del keystore: "); char[] password = in.readLine().toCharArray(); System.out.print("Password de la CA (" + aliasCA + "): "); char[] passwordCA = in.readLine().toCharArray(); System.out.print("Password del certificado (" + aliasCert + "): "); char[] passwordCert = in.readLine().toCharArray(); // Leer el keystore FileInputStream input = new FileInputStream(fich_keystore); KeyStore keystore = KeyStore.getInstance("JKS"); keystore.load(input, password); input.close(); // 1. Leer la clave privada y el certificado de la CA PrivateKey clavePrivadaCA = (PrivateKey)keystore.getKey(aliasCA, passwordCA); java.security.cert.Certificate certificadoCA = keystore.getCertificate(aliasCA); // 2. Crear una implementación X.509 para el certificado del CA byte[] codificado = certificadoCA.getEncoded(); X509CertImpl implementacionCA = new X509CertImpl(codificado); X509CertInfo infoCA = (X509CertInfo)implementacionCA.get (X509CertImpl.NAME + "." + X509CertImpl.INFO); X500Name emisorCA = (X500Name)infoCA.get (X509CertInfo.SUBJECT + "." + CertificateIssuerName.DN_NAME); // 3. Leer la clave privada y el certificado a firmar java.security.cert.Certificate cert = keystore.getCertificate(aliasCert); PrivateKey clavePrivada = (PrivateKey)keystore.getKey(aliasCert, passwordCert); // 4. Crear de nuevo otra implementación X.509 para el certificado a firmar como CA codificado = cert.getEncoded(); X509CertImpl implementacionCert = new X509CertImpl(codificado); X509CertInfo infoCert = (X509CertInfo)implementacionCert.get (X509CertImpl.NAME + "." + X509CertImpl.INFO); // 5. Especificar y almacenar el período de validez Date inicio = new Date(); Date fin = new Date(inicio.getTime() + VALIDEZ*24*60*60*1000L); CertificateValidity intervalo = new CertificateValidity(inicio, fin); infoCert.set(X509CertInfo.VALIDITY, intervalo); // 6. Crear y almacenar un número de serie infoCert.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber((int)(inicio.getTime()/1000))); // 7. Poner como emisor a la CA infoCert.set(X509CertInfo.ISSUER + "." + CertificateSubjectName.DN_NAME, emisorCA); // 8. Fijar el algoritmo AlgorithmId algoritmo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid); infoCert.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, algoritmo); // 9. Crear el nuevo certificado a partir del info X509CertImpl nuevoCert = new X509CertImpl(infoCert); // 10. Firmar el nuevo certificado que acabamos de crear nuevoCert.sign(clavePrivadaCA, ALG); // 11. Almacenar en el keystore keystore.setKeyEntry(aliasNuevo, clavePrivada, passwordCert, new java.security.cert.Certificate[] { nuevoCert } ); // 12. Almacenar el keystore en el fichero FileOutputStream output = new FileOutputStream(fich_keystore); keystore.store(output, password); output.close(); } }