2012-09-08 18 views
6

Die Frage ist, wie Zertifikatsketten programmgesteuert in Java generiert werden. Mit anderen Worten, würde Ich mag in Java hier detailliert die Vorgänge auszuführen: http://fusesource.com/docs/broker/5.3/security/i382664.htmlGenerate Zertifikatskette in Java

Besically ich den RSA-Schlüssel für einen neuen Kunden erstellen:

private KeyPair genRSAKeyPair(){ 
    // Get RSA key factory: 
    KeyPairGenerator kpg = null; 
    try { 
     kpg = KeyPairGenerator.getInstance("RSA"); 
    } catch (NoSuchAlgorithmException e) { 
     log.error(e.getMessage()); 
     e.printStackTrace(); 
     return null; 
    } 
    // Generate RSA public/private key pair: 
    kpg.initialize(RSA_KEY_LEN); 
    KeyPair kp = kpg.genKeyPair(); 
    return kp; 

}

und ich erzeugen die entsprechendes Zertifikat:

private X509Certificate generateCertificate(String dn, KeyPair pair, int days, String algorithm) 
    throws GeneralSecurityException, IOException { 
    PrivateKey privkey = pair.getPrivate(); 
    X509CertInfo info = new X509CertInfo(); 
    Date from = new Date(); 
    Date to = new Date(from.getTime() + days * 86400000l); 
    CertificateValidity interval = new CertificateValidity(from, to); 
    BigInteger sn = new BigInteger(64, new SecureRandom()); 
    X500Name owner = new X500Name(dn); 

    info.set(X509CertInfo.VALIDITY, interval); 
    info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn)); 
    info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner)); 
    info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner)); 
    info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic())); 
    info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3)); 
    AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid); 
    info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo)); 

    // Sign the cert to identify the algorithm that's used. 
    X509CertImpl cert = new X509CertImpl(info); 
    cert.sign(privkey, algorithm); 

    // Update the algorith, and resign. 
    algo = (AlgorithmId)cert.get(X509CertImpl.SIG_ALG); 
    info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, algo); 
    cert = new X509CertImpl(info); 
    cert.sign(privkey, algorithm); 
    return cert; 

}

Dann erzeuge ich die CERT Signaturanforderung und ich spare es csrFile Datei:

public static void writeCertReq(File csrFile, String alias, String keyPass, KeyStore ks) 
     throws KeyStoreException, 
       NoSuchAlgorithmException, 
       InvalidKeyException, 
       IOException, 
       CertificateException, 
       SignatureException, 
       UnrecoverableKeyException { 

    Object objs[] = getPrivateKey(ks, alias, keyPass.toCharArray()); 
    PrivateKey privKey = (PrivateKey) objs[0]; 

    PKCS10 request = null; 

    Certificate cert = ks.getCertificate(alias); 
    request = new PKCS10(cert.getPublicKey()); 
    String sigAlgName = "MD5WithRSA"; 
    Signature signature = Signature.getInstance(sigAlgName); 
    signature.initSign(privKey); 
    X500Name subject = new X500Name(((X509Certificate) cert).getSubjectDN().toString()); 
    X500Signer signer = new X500Signer(signature, subject); 
    request.encodeAndSign(signer); 
    request.print(System.out); 
    FileOutputStream fos = new FileOutputStream(csrFile); 
    PrintStream ps = new PrintStream(fos); 
    request.print(ps); 
    fos.close(); 
} 

wo

private static Object[] getPrivateKey(KeyStore ks, String alias, char keyPass[]) 
     throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException { 
    key = null;   
    key = ks.getKey(alias, keyPass); 
    return (new Object[]{ (PrivateKey) key, keyPass }); 
} 

Jetzt soll ich die CSR mit dem privaten CA-Schlüssel unterschreiben, aber ich kann nicht sehen, wie man achive das in Java. Ich habe "meinen eigenen" CA privaten Schlüssel in meinem jks.

Außerdem, sobald ich es schaffen, den CSR zu unterzeichnen, sollte ich das CA-Zertifikat mit dem signierten CSR verketten: wie kann das in Java gemacht werden?

Ich würde nicht gerne bc oder andere externe Bibliotheken verwenden, nur "sun.security" Klassen.

Vielen Dank.

Antwort

2

Entschuldigung, aber trotz Ihrer Wünsche, und abgesehen davon, dass Sie all Ihren Krypto-Code schreiben und ihn in Ihr Projekt einbeziehen (nicht empfohlen), empfehle ich Ihnen hier Bouncy Castle zu verwenden.

Spezifisch, bitte beziehen Sie sich auf https://stackoverflow.com/a/7366757/751158 - die enthält Code für genau, was Sie suchen zu tun.

+0

Ok. So sei es. Ich werde BC einbeziehen und ich werde von Ihrem Link profitieren. Vielen Dank –

1

Ich sehe, Sie sind schon zu der BouncyCastle-Seite des Hauses gegangen, nur für den Fall, dass sich jemand anderes fragen würde; Sie können die Zertifikatkette dem Eintrag hinzufügen, wenn Sie den Schlüssel in den KeyStore legen. Zum Beispiel

// build your certs 

KeyStore keyStore = KeyStore.getInstance("PKCS12"); 
keyStore.load([keystore stream], password.toCharArray());// or null, null if it's a brand new store 
X509Certificate[] chain = new X509Certificate[2]; 
chain[0] = _clientCert; 
chain[1] = _caCert; 
keyStore.setKeyEntry("Alias", _clientCertKey, password.toCharArray(), chain); 
keyStore.store([output stream], password.toCharArray()); 

// do other stuff