utiliza respuesta recomienda públicas propietario migrar las kit introduzca herramienta formato existe desarrollo crear contraseña coinciden claves certificados certificado archivo almacén almacen administración java security ssl bouncycastle digital-certificate

java - recomienda - las claves públicas en la respuesta y en el almacén de claves no coinciden



Guardar la cadena de certificados en un almacén de claves pkcs12 (2)

Dependiendo de qué JDK use, hay diferentes maneras de empaquetar su aplicación. Nos sucede cuando algunas personas utilizan Linux y OpenJDK y otras se desarrollan en Windows con SunJDK (Oracle).

Los últimos tienen algo de configuración adicional que hacer para poder usar los algoritmos más fuertes. Este artículo puede ayudarlo si su problema está relacionado con la Política de JCE.

El siguiente código:

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

donde certChain tiene el certificado final y el certificado del emisor (es decir, dos certificados),
no guarda el certificado del emisor como parte de la cadena en el archivo guardado en el sistema de archivos si el almacén de claves es una instancia de PKCS12 .

Guarda ambos certificados si el tipo de almacén de claves es PKCS12-3DES-3DES . ¿Por qué es esto? ¿Un PKCS12 no supone que ambos certificados sean parte de la cadena?

EDIT: Aquí hay un SSCCE . Esto funciona bien con "JKS" , falla con "PKCS12" : solo se puede acceder al primer certificado de la cadena a través de getCertificateChain(String) . El archivo guardado se puede abrir con openssl pkcs12 revelando ambos certificados.

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; }


Su código tiene 2 errores:

primero: no se configura el Emisor para el certificado (CA debe emitir el certificado de cliente para que la cadena sea válida)

segundo: se usa un orden incorrecto al crear la cadena de certificados (deben ser las notificaciones del cliente, la CA última)

Aquí está SSCCE reelaborado, y funciona sin errores.

@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; }