Sauvegarde de la chaîne de certificats dans un keystore pkcs12

Le code suivant:

//used Bouncy Castle provider for keyStore
keyStore.setKeyEntry(alias, (Key)keyPair.getPrivate(), pwd, certChain);  

où certChain détient le certificat final et le certificat de l'émetteur (c'est-à-dire deux certificats),

ne sauvegarde pas le certificat de l'émetteur dans la chaîne du fichier sauvegardé dans le fichier keystore du système Si le keyStore est une instance de PKCS12.

il sauve les deux certificats si le type de keystore est PKCS12-3DES-3DES. Pourquoi est-ce? Ne fait pas un PKCS12 supposer avoir les deux certificats font partie du la chaîne?

EDIT: Voici un SSCCE. Cela fonctionne bien avec "JKS", échoue avec "PKCS12": Seul le premier certificat de la chaîne est accessible via getCertificateChain(String). Le fichier peut être ouvert avec openssl pkcs12 révéler les deux certificats.

    public void testKeyStore() {
    try {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(1024);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        Certificate[] outChain = { createCertificate("CN=CA", publicKey, privateKey), createCertificate("CN=Client", publicKey, privateKey) };

        KeyStore outStore = KeyStore.getInstance("PKCS12");
        outStore.load(null, "secret".toCharArray());
        outStore.setKeyEntry("mykey", privateKey, "secret".toCharArray(), outChain);            
        OutputStream outputStream = new FileOutputStream("c:/outstore.pkcs12");
        outStore.store(outputStream, "secret".toCharArray());
        outputStream.flush();
        outputStream.close();

        KeyStore inStore = KeyStore.getInstance("PKCS12");      
        inStore.load(new FileInputStream("c:/outstore.pkcs12"), "secret".toCharArray());
        Key key = outStore.getKey("myKey", "secret".toCharArray());
        assertEquals(privateKey, key);

        Certificate[] inChain = outStore.getCertificateChain("mykey");
        assertNotNull(inChain);
        assertEquals(outChain.length, inChain.length);
    } catch (Exception e) {
        e.printStackTrace();
        fail(e.getMessage());
    }
}

private static X509Certificate createCertificate(String dn, PublicKey publicKey, PrivateKey privateKey) throws Exception {
    X509V3CertificateGenerator certGenerator = new X509V3CertificateGenerator();
    certGenerator.setSerialNumber(new BigInteger("1"));
    certGenerator.setIssuerDN(new X509Name(dn));
    certGenerator.setSubjectDN(new X509Name(dn));
    certGenerator.setNotBefore(Calendar.getInstance().getTime());
    certGenerator.setNotAfter(Calendar.getInstance().getTime());
    certGenerator.setPublicKey(publicKey);
    certGenerator.setSignatureAlgorithm("SHA1withRSA");
    X509Certificate certificate = (X509Certificate)certGenerator.generate(privateKey, "BC");
    return certificate;
}
21
demandé sur martijno 2012-11-03 12:21:55

2 réponses

Votre code a 2 erreur:

le premier: vous ne définissez pas L'émetteur pour le certificat (le certificat client doit être émis par L'AC pour rendre valide la chaîne).

deuxième: vous utilisez l'ordre erroné lors de la création de la chaîne de certificats (devrait être client ferts, CA last)

voici le sscce retravaillé, et il fonctionne sans erreurs.

@Test
public void testKeyStore() throws Exception{
        try {
        String storeName =  "/home/grigory/outstore.pkcs12";
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(1024);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        Certificate trustCert =  createCertificate("CN=CA", "CN=CA", publicKey, privateKey);
        Certificate[] outChain = { createCertificate("CN=Client", "CN=CA", publicKey, privateKey), trustCert };

        KeyStore outStore = KeyStore.getInstance("PKCS12");
        outStore.load(null, "secret".toCharArray());
        outStore.setKeyEntry("mykey", privateKey, "secret".toCharArray(), outChain);
        OutputStream outputStream = new FileOutputStream(storeName);
        outStore.store(outputStream, "secret".toCharArray());
        outputStream.flush();
        outputStream.close();

        KeyStore inStore = KeyStore.getInstance("PKCS12");
        inStore.load(new FileInputStream(storeName), "secret".toCharArray());
        Key key = outStore.getKey("myKey", "secret".toCharArray());
        Assert.assertEquals(privateKey, key);

        Certificate[] inChain = outStore.getCertificateChain("mykey");
        Assert.assertNotNull(inChain);
        Assert.assertEquals(outChain.length, inChain.length);
    } catch (Exception e) {
        e.printStackTrace();
        throw new AssertionError(e.getMessage());
    }
   }
    private static X509Certificate createCertificate(String dn, String issuer, PublicKey publicKey, PrivateKey privateKey) throws Exception {
        X509V3CertificateGenerator certGenerator = new X509V3CertificateGenerator();
        certGenerator.setSerialNumber(BigInteger.valueOf(Math.abs(new Random().nextLong())));
        certGenerator.setIssuerDN(new X509Name(dn));
        certGenerator.setSubjectDN(new X509Name(dn));
        certGenerator.setIssuerDN(new X509Name(issuer)); // Set issuer!
        certGenerator.setNotBefore(Calendar.getInstance().getTime());
        certGenerator.setNotAfter(Calendar.getInstance().getTime());
        certGenerator.setPublicKey(publicKey);
        certGenerator.setSignatureAlgorithm("SHA1withRSA");
        X509Certificate certificate = (X509Certificate)certGenerator.generate(privateKey, "BC");
        return certificate;
    }
15
répondu user1516873 2017-06-06 10:14:59

selon le JDK que vous utilisez, il y a différentes façons d'empaqueter votre application. Cela nous arrive quand certaines personnes utilisent Linux et OpenJDK et d'autres se développent sur Windows avec SunJDK (Oracle).

les derniers ont une configuration supplémentaire à faire pour pouvoir utiliser les algorithmes les plus forts. Cet article peut vous aider si votre problème est lié à la Politique de JCE.

0
répondu рüффп 2012-12-16 11:03:08