3 votes

Le certificat X509 signé avec bouncy castle n'est pas valide

J'ai parcouru un long chemin pour faire signer une CSR par java et j'ai enfin pu le faire, mais openssl dit que ce n'est pas valide. Le même CSR signé avec openssl passe l'étape de vérification.

Tout est la même version x509 (1), pas d'extensions, le sujet, l'émetteur sont les mêmes.

Je soupçonne que le problème se situe au niveau du DN de l'objet (surtout pour les courriels) ou des dates.

Vérification :

  openssl verify -verbose  -CAfile src/test/resources/ca.cer.pem o.cer.pem  
  o.cer.pem: OK

  openssl verify -verbose  -CAfile src/test/resources/ca.cer.pem client.cer.pem    
  client.cer.pem: C = RU, ST = Moscow, L = Moscow, O = Hoofs, OU = IT, CN = Danee Yaitskov    
  error 20 at 0 depth lookup:unable to get local issuer certificate

La taille des fichiers est similaire :

1229 28 juil. 12:45 client.cer.pem 1233 28 juil. 13:00 o.cer.pem

Il se plaint comme s'il y avait un certificat manquant dans la chaîne mais, je ne vois pas cette information.

Comment vérifier quel est le prochain certificat parental ?

Informations sur le bon certificat :

openssl x509 -in  o.cer.pem  -text -noout 
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number: 1192228 (0x123124)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=RU, ST=Moscow, L=Moscow, O=Hoofs, OU=IT, CN=www.hoofs.com/emailAddress=admin@hoofs.com
        Validity
            Not Before: Jul 28 11:00:01 2016 GMT
            Not After : Jul 28 11:00:01 2017 GMT
        Subject: C=RU, ST=Moscow, L=Moscow, O=Hoofs, OU=IT, CN=Danee Yaitskov
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:c2:94:04:69:58:3c:90:a9:0e:7e:23:78:9a:7c:
                    30:09:f1:5b:cf:0f:3c:d9:63:48:fb:97:77:2a:67:
                    85:20:30:a0:d6:57:4d:0c:55:5b:53:97:7b:5c:2f:
                    f5:6d:49:84:7d:59:6b:eb:3d:9b:84:ac:2c:bc:56:
                    1f:24:d4:d3:6b:be:0c:53:c4:e6:57:85:1e:95:9e:
                    37:9d:58:e1:e3:d5:5f:17:99:6c:69:2a:7e:9a:a5:
                    f4:11:69:54:b5:eb:71:ea:5d:a5:9f:b2:38:b7:47:
                    33:42:87:b5:83:64:0b:8c:d1:3c:2b:a4:a8:fd:6a:
                    1e:5c:1e:eb:c3:c2:f7:c6:10:95:65:b9:f4:15:97:
                    2a:88:c6:22:53:f5:63:92:89:05:ce:91:af:ee:4f:
                    4e:bb:a8:03:3c:ed:5b:0f:35:45:45:c3:a1:6f:af:
                    aa:87:21:94:ba:4d:63:25:fa:eb:65:1e:e0:34:75:
                    90:04:d4:71:4f:54:ed:e9:52:a1:b8:52:45:3b:03:
                    9f:15:80:3f:e6:d8:0d:32:55:df:e0:ea:78:34:e0:
                    30:64:dd:7c:77:b4:03:ce:d1:0d:ac:24:a7:b4:08:
                    63:3d:1a:9e:54:b1:2e:b1:b0:1d:24:b2:a6:9b:8d:
                    dc:3f:bd:ae:59:72:01:07:f8:e9:e8:c8:73:78:5c:
                    0c:b1
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
         a3:88:4c:84:5a:af:e3:35:6c:3d:a8:05:9b:7e:f5:a0:a3:b1:
         79:de:31:db:1e:ca:ce:d9:69:aa:88:8f:fb:78:04:aa:3b:c4:
         41:ed:13:77:3b:17:b5:62:9b:da:54:92:25:0e:46:71:a0:f1:
         43:28:d4:81:3f:be:a6:ce:53:3f:03:70:13:55:44:5f:f2:a5:
         ab:b0:d5:1f:84:70:84:f9:b5:74:cd:4a:f6:fc:bd:f8:71:bc:
         42:66:e0:a4:ec:4a:b6:26:e9:f9:fa:5e:67:fe:73:07:10:7d:
         e2:02:d7:a6:30:8e:20:fb:0c:f9:f6:3e:6e:80:87:6f:3b:30:
         c3:07:3d:af:ee:f7:e2:cc:0f:7d:71:39:fc:30:1a:15:1c:1f:
         7f:4a:7e:9d:80:a4:1a:8f:f5:d9:e9:0b:95:c9:3c:5c:88:6d:
         a7:66:2b:dc:b0:03:6e:f2:c5:b2:7a:85:35:0b:d6:8f:53:79:
         d7:13:28:3f:fb:2c:59:9c:69:df:8a:dd:96:f6:bd:b8:78:5e:
         b7:84:c5:48:d2:cf:4f:e8:a4:a8:d7:f5:91:d2:8c:94:95:9f:
         a5:b9:10:c2:87:4b:ee:fa:2d:1c:bb:8f:37:f6:56:20:1c:a5:
         aa:e9:77:bf:c4:29:92:67:14:81:76:43:e9:47:dd:5b:7d:9e:
         69:7a:73:ec

Information sur le mauvais certificat :

openssl x509 -in  client.cer.pem  -text -noout 
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number: 362342824 (0x1598e9a8)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=RU, ST=Moscow, L=Moscow, O=Hoofs, OU=IT, CN=www.hoofs.com/emailAddress=admin@hoofs.com
        Validity
            Not Before: Jul 28 10:45:12 2015 GMT
            Not After : Jul 28 10:45:12 2026 GMT
        Subject: C=RU, ST=Moscow, L=Moscow, O=Hoofs, OU=IT, CN=Danee Yaitskov
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:c2:94:04:69:58:3c:90:a9:0e:7e:23:78:9a:7c:
                    30:09:f1:5b:cf:0f:3c:d9:63:48:fb:97:77:2a:67:
                    85:20:30:a0:d6:57:4d:0c:55:5b:53:97:7b:5c:2f:
                    f5:6d:49:84:7d:59:6b:eb:3d:9b:84:ac:2c:bc:56:
                    1f:24:d4:d3:6b:be:0c:53:c4:e6:57:85:1e:95:9e:
                    37:9d:58:e1:e3:d5:5f:17:99:6c:69:2a:7e:9a:a5:
                    f4:11:69:54:b5:eb:71:ea:5d:a5:9f:b2:38:b7:47:
                    33:42:87:b5:83:64:0b:8c:d1:3c:2b:a4:a8:fd:6a:
                    1e:5c:1e:eb:c3:c2:f7:c6:10:95:65:b9:f4:15:97:
                    2a:88:c6:22:53:f5:63:92:89:05:ce:91:af:ee:4f:
                    4e:bb:a8:03:3c:ed:5b:0f:35:45:45:c3:a1:6f:af:
                    aa:87:21:94:ba:4d:63:25:fa:eb:65:1e:e0:34:75:
                    90:04:d4:71:4f:54:ed:e9:52:a1:b8:52:45:3b:03:
                    9f:15:80:3f:e6:d8:0d:32:55:df:e0:ea:78:34:e0:
                    30:64:dd:7c:77:b4:03:ce:d1:0d:ac:24:a7:b4:08:
                    63:3d:1a:9e:54:b1:2e:b1:b0:1d:24:b2:a6:9b:8d:
                    dc:3f:bd:ae:59:72:01:07:f8:e9:e8:c8:73:78:5c:
                    0c:b1
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
         71:17:8f:bb:09:05:91:0e:47:ba:f8:53:28:e3:d3:e3:b2:94:
         02:71:b1:d1:93:45:d7:a0:f2:be:1f:4d:a3:18:95:35:23:6a:
         1c:1d:4b:5f:60:cf:1c:93:22:1a:1b:4d:6c:e3:14:bc:7f:25:
         85:24:a5:00:fb:ed:36:23:ea:b2:51:6d:8a:f2:58:07:e9:5f:
         89:7e:8c:59:d2:1d:7c:85:69:bf:97:3f:f4:8f:3d:b4:21:4e:
         c3:ad:1a:bd:fa:22:03:85:a3:d2:9c:76:71:58:43:4e:3f:d8:
         d2:ec:8e:17:d0:53:65:c1:b7:82:38:fc:73:53:a1:80:38:1d:
         89:f6:e2:48:d8:ea:a6:f6:b4:46:95:2e:cb:36:b6:e5:c2:02:
         3f:bc:b2:82:a8:2e:02:7b:56:8e:59:c4:ee:1e:a5:40:bf:38:
         b9:28:e7:37:2c:95:ce:2d:0b:b1:45:43:9b:49:fe:ec:37:49:
         bd:f6:1e:7a:d2:2e:5c:8d:bc:00:e6:aa:96:16:83:72:8d:71:
         13:33:1c:8f:8c:c7:dd:e0:99:b3:98:ac:7d:52:83:00:34:0f:
         35:7a:55:d0:05:57:6c:a4:e0:5e:6d:58:a9:eb:79:e2:ae:e0:
         13:87:32:e4:78:eb:a7:31:64:bf:c4:13:6d:2d:85:a2:67:ec:
         62:d8:98:cb

Informations sur le certificat CA :

openssl x509 -in   src/test/resources/ca.cer.pem  -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 15043747854009729194 (0xd0c620f7d0cb80aa)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=RU, ST=Moscow, L=Moscow, O=Hoofs, OU=IT, CN=www.hoofs.com/emailAddress=admin@hoofs.com
        Validity
            Not Before: Apr  7 08:18:18 2016 GMT
            Not After : Apr  7 08:18:18 2017 GMT
        Subject: C=RU, ST=Moscow, L=Moscow, O=Hoofs, OU=IT, CN=www.hoofs.com/emailAddress=admin@hoofs.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:d4:7a:59:42:12:40:fb:4f:02:09:af:cf:6e:a1:
                    56:1e:4a:1d:9b:8e:5c:4a:53:5b:63:34:f1:ac:5c:
                    4c:de:e8:2c:f0:6b:14:58:ec:64:a7:9f:1d:54:4a:
                    36:b7:11:4f:65:d6:bd:9b:9a:b5:b7:df:d7:41:e1:
                    f0:2e:8f:c8:88:d5:bc:56:ab:f5:cd:fc:f5:0c:0f:
                    25:a5:c9:78:cc:e3:74:86:3e:58:51:ce:18:d4:9c:
                    61:85:5f:de:08:2c:65:17:a2:ad:0e:05:63:92:58:
                    c4:76:ee:02:2c:68:41:4e:a9:8f:8f:2e:98:82:47:
                    39:eb:60:a2:5c:ee:0a:55:23:5e:d6:cd:d2:29:94:
                    0d:e0:cd:82:b0:af:83:61:93:22:99:b1:5c:f2:f8:
                    3b:71:30:5b:26:46:3e:15:d0:26:d7:70:ae:34:31:
                    35:a4:39:f7:dd:e4:99:4f:68:42:78:9a:90:70:4a:
                    8d:0f:08:2d:80:b2:2a:23:5e:55:b9:28:52:dd:ce:
                    15:bd:77:41:66:3f:1b:dc:9f:47:89:b3:e2:0d:f0:
                    25:5e:5e:47:d4:f9:e9:f6:fb:8e:08:7e:52:5f:bd:
                    bd:4d:2a:bf:ed:08:6a:7f:4c:32:21:c6:c0:6a:53:
                    84:f8:1d:37:47:0d:93:e7:90:90:2b:7c:03:db:7a:
                    40:fb
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                B7:2A:B2:C4:63:E8:E3:D5:7A:A7:30:4D:5B:E8:C3:2D:5A:72:BC:DE
            X509v3 Authority Key Identifier: 
                keyid:B7:2A:B2:C4:63:E8:E3:D5:7A:A7:30:4D:5B:E8:C3:2D:5A:72:BC:DE

            X509v3 Basic Constraints: 
                CA:TRUE
    Signature Algorithm: sha256WithRSAEncryption
         3a:74:2d:13:96:06:26:35:7d:cc:44:28:d2:9a:47:e4:08:9e:
         c5:ef:91:b7:6f:66:e1:bd:96:92:28:b1:13:3b:f3:2d:57:4f:
         85:c6:e8:7d:53:3f:ba:c3:78:80:da:4e:ba:a8:85:e2:22:b2:
         19:5d:62:2a:7d:ed:48:ab:b4:22:7a:9a:f1:83:b8:04:0d:87:
         dc:9e:61:fd:e7:e8:2e:c4:12:6e:b9:6b:b0:14:79:35:86:91:
         e8:f0:de:00:b8:bd:7e:d0:d1:4c:33:db:c3:f0:05:b7:06:2a:
         21:33:4b:82:e5:74:7d:65:d8:ce:81:7f:f3:6f:03:c8:5c:aa:
         de:fd:24:46:aa:20:95:d6:bc:91:ee:f9:ec:d0:c8:e5:9e:8d:
         1c:44:1b:6c:05:4a:a9:bd:19:86:61:f0:5f:75:12:46:28:80:
         29:79:c2:1e:e8:1c:e7:48:38:7d:7a:40:c8:ca:c9:4d:b1:a9:
         5c:53:90:33:4f:13:70:93:97:73:0a:84:ac:31:0e:8e:a6:cb:
         c4:53:b7:c8:0c:9e:15:22:11:0a:b8:db:5a:95:6a:d2:26:49:
         e4:4e:3a:c0:9f:47:95:29:db:84:bc:6a:da:25:ba:96:05:33:
         d6:1c:23:5a:76:36:75:4f:ce:19:f8:ff:27:5e:e0:4f:c3:77:
         2a:63:63:6e

Commande pour la signature de CSR avec openssl

openssl  x509 -req -days ${DAYS:-365} -in src/test/resources/client.csr   -CA src/test/resources/ca.cer.pem -CAkey src/test/resources/ca.key.pem -out o.cer.pem -CAserial serial 

Code Java pour la signature du CSR (bouncycastle 1.54 sur java8) :

    @Test
    @SneakyThrows
    public void sign() {
        Security.addProvider(new BouncyCastleProvider());
        X509Certificate caCert = loadCert("/ca.cer.pem");
        PrivateKey caKey = readPrivateKey("/ca.key.pem");
        try (InputStream csr = getClass().getResourceAsStream("/client.csr")) {
            String cert = signCSR(new InputStreamReader(csr), caKey, caCert);
            assertNotNull(cert);
            Files.write(Paths.get("client.cer.pem"), cert.getBytes());
        }

    }

    @SneakyThrows
    public byte[] readFile(String path) {
        try (InputStream keyStream =  getClass().getResourceAsStream(path)) {
            return IOUtils.toByteArray(keyStream);
        }
    }

    public static final char[] PASSWORD = "12312312".toCharArray();

    @SneakyThrows
    public PrivateKey readPrivateKey(String privateKeyPath) {
        PEMParser keyReader = new PEMParser(new InputStreamReader(getClass()
                .getResourceAsStream(privateKeyPath)));

        JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
        converter.setProvider(new BouncyCastleProvider());

        PKCS8EncryptedPrivateKeyInfo keyPair = (PKCS8EncryptedPrivateKeyInfo) keyReader.readObject();

        final JceOpenSSLPKCS8DecryptorProviderBuilder jceOpenSSLPKCS8DecryptorProviderBuilder = new JceOpenSSLPKCS8DecryptorProviderBuilder();
        jceOpenSSLPKCS8DecryptorProviderBuilder.setProvider("BC");
        InputDecryptorProvider pkcs8Prov = jceOpenSSLPKCS8DecryptorProviderBuilder.build(PASSWORD);

        PrivateKeyInfo pk = keyPair.decryptPrivateKeyInfo(pkcs8Prov);
        return converter.getPrivateKey(pk);
    }

    @SneakyThrows
    public X509Certificate loadCert(String path) {
        try (InputStream caStream = getClass().getResourceAsStream(path)) {
            X509CertificateHolder holder = (X509CertificateHolder) new PEMParser(
                    new InputStreamReader(caStream))
                    .readObject();
            CertificateFactory cf = CertificateFactory.getInstance("X509",
                    new BouncyCastleProvider());
            return (X509Certificate) cf.generateCertificate(
                    new ByteArrayInputStream(holder.getEncoded()));
        }
    }

    public static String signCSR(Reader pemcsr, PrivateKey cakey, X509Certificate cacert) throws Exception {
        PEMParser reader = new PEMParser(pemcsr);
        PKCS10CertificationRequest csr = (PKCS10CertificationRequest) reader.readObject();

        AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256withRSA");
        AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);

        X500Name issuer = new X500NameBuilder( BCStrictStyle.INSTANCE )
                .addRDN(BCStrictStyle.C, "RU")
                .addRDN( BCStyle.ST, "Moscow")
                .addRDN( BCStyle.L, "Moscow" )
                .addRDN(BCStyle.O, "Hoofs")
                .addRDN(BCStyle.OU, "IT")
                .addRDN(BCStyle.CN, "www.hoofs.com/emailAddress=admin@hoofs.com")

                .build();

        BigInteger serial = new BigInteger(32, new SecureRandom());
        Date from = new DateTime().minusYears(1).toDate();
        Date to = new DateTime().plusYears(10).toDate();

        X509v1CertificateBuilder certBuilder = new X509v1CertificateBuilder(
        issuer, serial,
                from, to, csr.getSubject(), csr.getSubjectPublicKeyInfo());

        ContentSigner signer = new BcRSAContentSignerBuilder(sigAlgId, digAlgId)
                .build(PrivateKeyFactory.createKey(cakey.getEncoded()));
        X509CertificateHolder holder = certBuilder.build(signer);
        byte[] certencoded = holder.toASN1Structure().getEncoded();

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        out.write("-----BEGIN CERTIFICATE-----\n".getBytes());
        out.write(java.util.Base64.getMimeEncoder(64, "\n".getBytes()).encode(certencoded));
        out.write("\n-----END CERTIFICATE-----\n".getBytes());
        out.close();
        return new String(out.toByteArray());
    }

2voto

pedrofb Points 19206

J'ai un exemple similaire qui fonctionne

Essayez de remplacer X500Name issuer = avec le nom du X500 obtenu de CA pour éviter les problèmes avec les caractères

X500Name issuer = X500Name.getInstance(cacert.getSubjectX500Principal().getEncoded());

Aussi, je pense que vous avez besoin de cette partie avant l'encodage PEM.

CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
signer = new JcaContentSignerBuilder("SHA1withRSA").build(cakey);
generator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build()).build(signer, cacert));
generator.addCertificate(new X509CertificateHolder(certencoded));
generator.addCertificate(new X509CertificateHolder(cacert.getEncoded()));
CMSTypedData content = new CMSProcessableByteArray(certencoded);
CMSSignedData signeddata = generator.generate(content, true);
byte signedCertificate[] = signeddata.getEncoded();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X