Certificat importé à Java keystore, JVM ignore le nouveau cert

j'essaie de faire tourner une application sur Tomcat 6 pour me connecter à un serveur LDAP sur SSL.

j'ai importé le certificat du serveur à keystore en utilisant:

C:Program FilesJavajdk1.6.0_32jrelibsecurity>keytool -importcert -trustcacerts -file mycert -alias ca_alias -keystore "c:Program FilesJavajdk1.6.0_32jrelibsecuritycacerts"

quand je démarre Tomcat avec le débogage SSL activé, selon les journaux, Tomcat utilise le bon fichier de certificats:

trustStore is: C:Program FilesJavajdk1.6.0_32jrelibsecuritycacerts

cependant, Tomcat n'ajoute pas le certificat que je viens d'importer - tous les autres certificats du fichier cacerts sont imprimés sur le log - and connection échoue:

handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Redémarrer Tomcat n'aide pas. J'ai vérifié avec la commande keytool-list que le nouveau cert existe bien sur le fichier.

pourquoi Tomcat continue d'ignorer mon nouveau cert?

EDIT:

semble que le problème a été causé par Windows 7 VirtualStore. Keytool a créé une nouvelle copie du fichier cacert, et Tomcat a utilisé le fichier original.

18
demandé sur wattostudios 2012-05-07 18:26:37

4 réponses

JVM doit être redémarré après l'importation des certs dans le keystore.

15
répondu SSLKida 2017-12-06 09:24:03

Vérifiez s'il y a une clé avec les mêmes informations CN mais un alias différent.

j'ai déjà eu des problèmes similaires lorsque j'ai essayé d'importer une nouvelle version d'un certificat, mais j'ai laissé l'ancienne version dans le keystore. Mes programmes Java trouveraient simplement la première clé CN correspondante dans le keystore (qui était l'ancienne clé expirée) et essayeraient de l'utiliser, même s'il y en avait une plus récente qui correspondait aussi au CN.

s'assurer également que la racine d'authentification le certificat (et le certificat intermédiaire s'il y a lieu) existe dans le keystore. Si vous vous authentifiez contre L'un des principaux fournisseurs de sécurité tels que Verisign ou Globalsign, ils vous fourniront généralement les certificats racine et intermédiaire. Si ces certificats existent déjà dans le keystore, assurez-vous qu'ils sont toujours valides. Vous devez avoir tous les certificats de votre certificat personnel tout au long de la chaîne d'authentification à la racine, existant dans votre fichier de clés, de sorte qu'il comprend comment valider vos informations d'identification.

5
répondu wattostudios 2012-05-07 14:47:56

ce que vous avez décrit est exactement ce que J'ai obtenu en utilisant cmd.exe et un utilisateur régulier bien que membre du groupe administratif sur un serveur Windows. Vous devez commencer cmd.exe en mode administration pour appliquer les modifications aux fichiers cacerts. Au moins sur L'OSs Win2k8.

si vous ne faites pas ce carets vous montrera dans le keytool.exe -list voir les certs nouvellement ajoutés mais Tomcat ne les verra pas. Je ne sais pas pourquoi. Mais quand vous l'ajoutez avec cmd.exe a commencé en tant Qu'administrateur Tomcat est d'accord avec les nouveaux certs ajoutés.

vous pouvez aussi utiliser Djavax.net.debug="ssl,handshake" pour voir ce que Tomcat lit dans le fichier cacerts.

2
répondu jturunen 2013-09-24 12:39:50

dans mon cas, j'ai examiné tellement de choses avant de comprendre ce qui n'allait pas... J'ai ajouté le certificat à différentes keystores, j'ai ajouté tous les certificats dans la chaîne (ce qui est inutile btw), j'ai téléchargé le cert à nouveau pour ma propre santé mentale et vérifié le numéro de série, et même inspecté le cert téléchargé pour s'assurer qu'il avait toutes les informations correctes.

j'ai fini par écrire un TLS vérifiant l'application client afin de déboguer le problème. Non seulement le serveur distant que j'étais se connectant au support TLS 1.2 (désactivé par défaut dans ma version de Java 7), le serveur n'a également pris en charge aucun des chiffreurs qui étaient activés dans mon client. Il s'avère que Java 7 avait moins de la moitié de ses codes supportés activés, beaucoup d'entre eux étant vraiment peu sûr et certains des plus sûrs étaient désactivés.

après quelques contre-vérifications, j'ai trouvé la liste suivante de TLS 1.2-supported secure ciphers:

new String[] {
    "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
    "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
    "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256",
    "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
    "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256",
    "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
    "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
    "TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384",
    "TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256",
    "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
    "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
    "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384",
    "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256",
    "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
    "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
    "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
    "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
    "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
    "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
    "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
    "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
    "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",
    "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
    "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",
    "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
    "TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256",
    "TLS_DHE_RSA_WITH_AES_256_CCM",
    "TLS_DHE_RSA_WITH_AES_128_CCM",
    "TLS_DHE_PSK_WITH_AES_256_CCM",
    "TLS_DHE_PSK_WITH_AES_128_CCM",
    "TLS_CHACHA20_POLY1305_SHA256",
    "TLS_AES_256_GCM_SHA384",
    "TLS_AES_128_GCM_SHA256",
    "TLS_AES_128_CCM_SHA256"
}

S'il y a des experts en cryptographie autour, n'hésitez pas à mettre à jour cette liste. J'ai utilisé Qualys SSL Labs,c'Sécurité de l'Information SE répondre et IANA comme mes sources.

pour ceux qui veulent un échantillon du code source que j'ai utilisé, voir ci-dessous. J'utilisais Apache Commons HttpClient 3.0, donc vous aurez probablement besoin de télécharger ce qui suit binaires:

TLS12SocketFactory.java

import java.io.*;
import java.net.*;
import java.util.*;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.*;
import org.apache.commons.lang.StringUtils;

public class TLS12SocketFactory implements SecureProtocolSocketFactory {

        private final SecureProtocolSocketFactory base;
        public TLS12SocketFactory()
        {
            this.base = (SecureProtocolSocketFactory)Protocol.getProtocol("https").getSocketFactory();
        }
        private Socket acceptOnlyTLS12(Socket socket)
        {
            if(socket instanceof javax.net.ssl.SSLSocket) {
                final javax.net.ssl.SSLSocket s = (javax.net.ssl.SSLSocket)socket;

                // Set TLS 1.2
                s.setEnabledProtocols(new String[]{ "TLSv1.2" });

                // Using recommended ciphers from https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#table-tls-parameters-4
                List<String> recommended = new ArrayList(Arrays.asList(new String[]{ "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256", "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256", "TLS_DHE_RSA_WITH_AES_256_CCM", "TLS_DHE_RSA_WITH_AES_128_CCM", "TLS_DHE_PSK_WITH_AES_256_CCM", "TLS_DHE_PSK_WITH_AES_128_CCM", "TLS_CHACHA20_POLY1305_SHA256", "TLS_AES_256_GCM_SHA384", "TLS_AES_128_GCM_SHA256", "TLS_AES_128_CCM_SHA256" }));
                recommended.retainAll(Arrays.asList(s.getSupportedCipherSuites()));
                if(recommended.size() == 0) {
                    System.err.println("No supported modern ciphers. Update crypto policy or install JCE Unlimited Strength Jurisdiction Policy files." + System.lineSeparator());
                } else if(recommended.size() < 3) {
                    System.out.println("Few supported modern ciphers. It's recommended to update crypto policy or install JCE Unlimited Strength Jurisdiction Policy files." + System.lineSeparator());
                }
                s.setEnabledCipherSuites(recommended.toArray(new String[0]));

                // Log matched cipher and cert
                s.addHandshakeCompletedListener(new javax.net.ssl.HandshakeCompletedListener() {
                    @Override
                    public void handshakeCompleted(javax.net.ssl.HandshakeCompletedEvent hce) {
                        String print = s.getInetAddress().getHostName() + System.lineSeparator() + hce.getCipherSuite() + System.lineSeparator();
                        try {
                            for(java.security.cert.Certificate cert : hce.getPeerCertificates()) {
                                List<String> certStrings = Arrays.asList(cert.toString().split("\r?\n"));
                                for(int line = 0; line < certStrings.size(); line++) {
                                    if(certStrings.get(line).startsWith("Certificate Extensions:")) {
                                        print += System.lineSeparator() + StringUtils.join(certStrings.subList(2, line-1), System.lineSeparator()) + System.lineSeparator();
                                        break;
                                    }
                                }
                            }
                        } catch (javax.net.ssl.SSLPeerUnverifiedException ex) {
                            print += "Non-certificate based cipher used" + System.lineSeparator();
                        }
                        System.out.println(print);
                    }
                });
            }
            return socket;
        }

        @Override
        public Socket createSocket(String host, int port) throws IOException
        {
            return acceptOnlyTLS12(base.createSocket(host, port));
        }
        @Override
        public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) throws IOException
        {
            return acceptOnlyTLS12(base.createSocket(host, port, localAddress, localPort));
        }
        @Override
        public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params) throws IOException
        {
            return acceptOnlyTLS12(base.createSocket(host, port, localAddress, localPort, params));
        }
        @Override
        public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException
        {
            return acceptOnlyTLS12(base.createSocket(socket, host, port, autoClose));
        }
}

Main.java

import java.io.*;
import java.security.*;
import java.security.cert.*;
import java.util.*;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.*;
import org.apache.commons.httpclient.params.HttpClientParams;

public class Main {
    public static void main(String[] args) {
        List<java.net.URI> locations = new ArrayList<>();
        for(String arg : args) {
            java.net.URI location = java.net.URI.create(arg);
            if(location.isAbsolute() && location.getScheme().equals("https")) {
                locations.add(location);
            } else {
                System.out.println("Skipping invalid URL: " + arg);
            }
        }
        System.out.println("Connecting to URL's");
        System.out.println();
        System.out.println("-------------------------");

        TLS12SocketFactory tls12factory = new TLS12SocketFactory();
        Protocol.registerProtocol("httpss", new Protocol("httpss", tls12factory, 443));
        for(java.net.URI location : locations) {
            System.out.println();
            try {
                // Form request
                String tls12url = location.toString().replaceFirst("^https:", "httpss:");
                HttpMethod method = new HeadMethod(tls12url);

                // Send request
                HttpClientParams params = new HttpClientParams();
                params.setParameter(HttpClientParams.COOKIE_POLICY, CookiePolicy.IGNORE_COOKIES);
                new HttpClient(params).executeMethod(method);
                method.setFollowRedirects(true);

                // Print response
                System.out.println(location.toString());
                System.out.println(method.getStatusLine().toString());
            } catch (javax.net.ssl.SSLHandshakeException ex) {
                System.out.println("There was an error making a secure connection to " + location.getHost());
                ex.printStackTrace(System.out);
            } catch (HttpException ex) {
                System.out.println("There was an error with the external webpage");
                ex.printStackTrace(System.out);
            } catch (Exception ex) {
                System.out.println("Could not complete request");
                ex.printStackTrace(System.out);
            }
        }
        System.out.println();
        System.out.println("-------------------------");
        System.out.println();
        try {
            // Load supported SSL Ciphers
            System.out.println("Supported ciphers");
            System.out.println();
            System.out.println("-------------------------");
            System.out.println();
            javax.net.ssl.SSLSocket socket = (javax.net.ssl.SSLSocket)tls12factory.createSocket("www.google.com", 443);
            for(String cipher : socket.getSupportedCipherSuites()) {
                System.out.println(cipher);
            }
            System.out.println();
            System.out.println("-------------------------");
            System.out.println();

            // Load enabled SSL Ciphers
            System.out.println("Enabled ciphers");
            System.out.println();
            System.out.println("-------------------------");
            System.out.println();
            for(String cipher : socket.getEnabledCipherSuites()) {
                System.out.println(cipher);
            }
            System.out.println();
            System.out.println("-------------------------");
            System.out.println();

            // Load the JDK's cacerts keystore file
            String filename = System.getProperty("java.home") + "/lib/security/cacerts".replace('/', File.separatorChar);
            System.out.println("Loading keystore");
            System.out.println(filename);
            System.out.println();
            System.out.println("-------------------------");
            System.out.println();
            FileInputStream is = new FileInputStream(filename);
            KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
            String password = "changeit";
            keystore.load(is, password.toCharArray());

            // This class retrieves the most-trusted CAs from the keystore
            PKIXParameters params = new PKIXParameters(keystore);

            // Get the set of trust anchors, which contain the most-trusted CA certificates
            for (TrustAnchor ta : params.getTrustAnchors()) {
                // Print certificate
                System.out.println(ta.getTrustedCert());
            }
        } catch (CertificateException | KeyStoreException | NoSuchAlgorithmException | InvalidAlgorithmParameterException | IOException ex) {
            System.out.println("Could not load keystore");
            ex.printStackTrace(System.out);
        }
    }
}
0
répondu Pluto 2018-09-06 16:42:35