2016-07-28 5 views
3

Ich ging einen ziemlich langen Weg, um Java ein CSR zu unterzeichnen und schließlich konnte ich dies tun, aber openssl sagt, dass es nicht gültig ist. Derselbe CSR, der mit openssl signiert wurde, besteht den Bestätigungsschritt.X509 Zertifikat mit Hüpfburg unterzeichnet ist nicht gültig

Alle ist die gleiche x509-Version (1), keine Erweiterungen, Betreff, Aussteller sind gleich.

Ich vermute, das Problem ist mit Thema DN (insbesondere E-Mail) oder Daten.

Überprüfung:

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 

Dateigrößen sind ähnlich:

1229 28 Jul 12.45 client.cer.pem 1233 28. Juli 13.00 Uhr o.cer.pem

Es beschwert sich, als gäbe es ein fehlendes Zertifikat in der Kette, aber solche Informationen sehe ich nicht.

Wie überprüft man, was das nächste Elternzertifikat ist?

Info über gutes Zertifikat:

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/[email protected] 
     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 

Info über schlechtes Zertifikat:

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/[email protected] 
     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 

Info über CA-Zertifikat:

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/[email protected] 
     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/[email protected] 
     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 

Befehl zur Unterzeichnung CSR mit 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 

Java-Code für die Unterzeichnung CSR (bouncycastle 1,54 auf 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/[email protected]") 

       .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()); 
    } 
+0

*** 'CN = www.hoofs.com' *** ist zwielichtig. DNS-Namen gehen in den Subject Alt Name (SAN). Wenn ein DNS-Name im CN ist, muss er auch im SAN vorhanden sein (yep, Sie müssen ihn zweimal auflisten, daher ist es einfacher, ihn im SAN zu platzieren). Die Regeln und Gründe dafür finden Sie unter [Wie unterschreiben Sie eine Zertifikatsignierungsanforderung mit Ihrer Zertifizierungsstelle?] (Http://stackoverflow.com/a/21340898/608639) und [Wie erstelle ich ein selbstsigniertes Zertifikat mit openssl? ] (http://stackoverflow.com/q/10175812/608639) – jww

+0

* "So überprüfen Sie, welches das nächste übergeordnete Zertifikat ist ..." * - Der Aussteller des Betreffenden ist das nächste übergeordnete Zertifikat. Gehen Sie die Kette/den Pfad hinauf, bis Sie einen Vertrauensanker treffen. Wenn der Betreff und der Aussteller identisch sind, haben Sie den selbstsignierten Stamm gefunden. Es ist der letzte Ort, wo Sie Ihr Vertrauen verwurzeln können. Es ist in Ordnung, Root-Vertrauen früher in einem Zwischenzertifikat. – jww

Antwort

2

Ich habe ein ähnliches Beispiel arbeitet

Versuchen X500Name issuer = mit dem X500 Namen von CA bekam ersetzt Probleme mit Zeichen zu vermeiden

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

Außerdem glaube ich Ihnen diesen Teil vor PEM-Codierung benötigen haben

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(); 
+1

hast du meinen Tag gerettet! Dieser Trick bestand darin, dass der Name des Ausstellers sich von dem von openssl gedruckten Wert unterscheidet. C = RU, ST = Moskau, L = Moskau, O = Hufe, OU = IT, CN = www.hoofs.com, E = admin @ hoofs.com –

+0

Ok, ich hatte genau das gleiche Problem mit X509Name – pedrofb

Verwandte Themen