2016-07-28 5 views
3

Я прошел довольно длинный путь, чтобы сделать java знак CSR, и, наконец, я смог это сделать, но openssl сообщает, что это неверно. Тот же CSR, подписанный с openssl, проходит этап проверки.Сертификат X509, подписанный с надувным замком, недействителен

Все одинаковые версии x509 (1), без расширений, Subject, Эмитент - это то же самое.

Я подозреваю, что проблема связана с вопросом DN (особенно электронная почта) или датами.

Проверка:

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 

Размеры файлов похожи:

1229 28 июля 12:45 client.cer.pem 1233 28 июля 13:00 o.cer.pem

It жалуется, что в цепочке отсутствует сертификат, но я не вижу такой информации.

Как проверить, что является следующим родительским сертификатом?

Информация о хорошем сертификате:

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 

Информация о плохом сертификате:

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 

Информация о 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/[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 

Команда для подписания CSR с 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 код для подписания CSR (BouncyCastle 1.54 на 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' *** является изворотливым. Имена DNS перечисляются в имени объекта Alt (SAN). Если DNS-имя находится в CN, то оно также должно присутствовать в SAN (да, вы должны перечислить его дважды, поэтому его проще разместить в SAN). По правилам и причинам, почему, см. [Как вы подписываете запрос подписи сертификата в своем сертификационном центре?] (Http://stackoverflow.com/a/21340898/608639) и [Как создать самозаверяющий сертификат с помощью openssl? ] (http://stackoverflow.com/q/10175812/608639) – jww

+0

* «Как проверить, что является следующим родительским сертификатом ...» * - эмитент субъекта является следующим родительским сертификатом. Пройдите по цепочке/пути, пока не нажмете якорь доверия. Когда субъект и эмитент совпадают, вы попали в самозаверяющий корень. Это последнее место, где вы можете доверять себе доверие. Доверяйте его правильному доверию раньше, в промежуточном сертификате. – jww

ответ

2

У меня есть аналогичный пример рабочего

Попробуйте заменить X500Name issuer = с именем X500 получил от ЦС, чтобы избежать проблем с символами

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

Кроме того, я думаю, что у вас есть нужна эта часть перед кодированием 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(); 
+1

ты спас мой день! Этот трюк состоял в том, что имя эмитента отличается от значения, напечатанного openssl. C = RU, ST = Москва, L = Москва, O = Hoofs, OU = IT, CN = www.hoofs.com, E = admin @ hoofs.com –

+0

Хорошо, у меня была точно такая же проблема с X509Name – pedrofb

Смежные вопросы