2017-08-15 3 views
2

Je voudrais générer une paire de clés et l'insérer dans un KeyStore Java par programmation. Je peux utiliser la ligne de commande pour faire exactement ce que je veux, mais comment le faire en utilisant le code Java?Comment puis-je générer une paire de clés et l'insérer dans un KeyStore par programmation (sans utiliser Java KeyTool)?

Voici la ligne de commande:

keytool -genkeypair \ 
    -dname "cn=Unknown" \ 
    -alias main \ 
    -keyalg RSA \ 
    -keysize 4096 \ 
    -keypass 654321 \ 
    -keystore C:\\Users\\Felipe\\ks \ 
    -storepass 123456 \ 
    -validity 365 

Voici le code Java je jusqu'à présent:

public static void main(String[] args) { 
    try (
     FileOutputStream fos = new FileOutputStream("C:\\Users\\Felipe\\ks"); 
    ) { 
     KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); 
     keyPairGenerator.initialize(4096, SecureRandom.getInstance("SHA1PRNG")); 
     KeyPair keyPair = keyPairGenerator.generateKeyPair(); 

     Certificate[] chain = {}; 

     KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
     keyStore.load(null, null); 
     keyStore.setKeyEntry("main", keyPair.getPrivate(), "654321".toCharArray(), chain); // Error: Private key must be accompanied by certificate chain 
     keyStore.store(fos, "123456".toCharArray()); 
    } catch (NoSuchAlgorithmException | KeyStoreException | CertificateException | IOException e) { 
     e.printStackTrace(); 
    } 
} 

Mais je continue à recevoir le message d'erreur suivant: Private key must be accompanied by certificate chain.

Je pense que je devrais créer un certificat et l'insérer dans la matrice de certificat, mais comment faire cela?

Répondre

1

est ici une fonction bien Java pour générer auto des certificats signés par programme (link):

private X509Certificate generateCertificate(String dn, KeyPair keyPair, int validity, String sigAlgName) throws GeneralSecurityException, IOException { 
    PrivateKey privateKey = keyPair.getPrivate(); 

    X509CertInfo info = new X509CertInfo(); 

    Date from = new Date(); 
    Date to = new Date(from.getTime() + validity * 1000L * 24L * 60L * 60L); 

    CertificateValidity interval = new CertificateValidity(from, to); 
    BigInteger serialNumber = new BigInteger(64, new SecureRandom()); 
    X500Name owner = new X500Name(dn); 
    AlgorithmId sigAlgId = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid); 

    info.set(X509CertInfo.VALIDITY, interval); 
    info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(serialNumber)); 
    info.set(X509CertInfo.SUBJECT, owner); 
    info.set(X509CertInfo.ISSUER, owner); 
    info.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic())); 
    info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3)); 
    info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(sigAlgId)); 

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

    // Update the algorith, and resign. 
    sigAlgId = (AlgorithmId) certificate.get(X509CertImpl.SIG_ALG); 
    info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, sigAlgId); 
    certificate = new X509CertImpl(info); 
    certificate.sign(privateKey, sigAlgName); 

    return certificate; 
} 

Vous pouvez l'utiliser pour générer un certificat de votre paire de clés et l'insérer dans la chaîne de certificats afin de rendre la setKeyEntry() méthode travail:

public static void main(String[] args) { 
    try (
     FileOutputStream fos = new FileOutputStream("C:\\Users\\Felipe\\ks"); 
    ) { 
     KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); 
     keyPairGenerator.initialize(4096, SecureRandom.getInstance("SHA1PRNG")); 
     KeyPair keyPair = keyPairGenerator.generateKeyPair(); 

     Certificate[] chain = {generateCertificate("cn=Unknown", keyPair, 365, "SHA256withRSA")}; 

     KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
     keyStore.load(null, null); 
     keyStore.setKeyEntry("main", keyPair.getPrivate(), "654321".toCharArray(), chain); 
     keyStore.store(fos, "123456".toCharArray()); 
    } catch (IOException | GeneralSecurityException e) { 
     e.printStackTrace(); 
    } 
}