Является ли это допустимым подходом для принятия самозаверяющих сертификатов?

#java #certificate

#java #сертификат

Вопрос:

Я написал этот код, чтобы принимать все самозаверяющие сертификаты с сервера:

 private TrustManager[] createTrustManager() {
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                if (!chain[0].getIssuerDN().equals(chain[0].getSubjectDN())) {
                    throw new CertificateException("This is not a self-signed certificate");
                }
            }

            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                // leave blank to trust every client
            }
        }};
        return trustAllCerts;
    }
  

Является ли это допустимым и достаточным подходом?

Комментарии:

1. Вы используете Apache HttpClient или Sun HttpURLConnection ?

Ответ №1:

Хотя он выполняет свою работу, ваш подход в основном отрицает назначение правильного PKI. Если вы слепо доверяете любому самозаверяющему сертификату, тогда вообще нет смысла использовать TLS — любой может создать самозаверяющий сертификат, который передаст ваш TrustManager .

Итак, если вы хотите быть в безопасности, сначала вам следует выяснить, с какими серверами будет взаимодействовать ваше клиентское приложение, а затем получить сертификаты сервера TLS, которые связаны с этими службами (в вашем сценарии каждый из них самозаверяющий, поэтому вам не нужно заботиться о промежуточных сертификатах).

Теперь, используя эти сертификаты, вы создаете файл «хранилища доверия» JKS и помещаете в него сертификаты — это набор сертификатов, которым вы собираетесь доверять, сертификаты, не содержащиеся в этом файле, будут отклонены. Чтобы создать файл JKS, вы можете либо использовать команду keytool Java, либо сделать это программно с помощью KeyStore API.

Наконец, вы бы создали SSLContext , который будет использоваться вашим HttpClient и init ит, TrustManager созданным следующим образом:

 KeyStore ks = KeyStore.getInstance("JKS");
ks.load(fin, pwd);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
tmf.init(ks);
  

где fin находится InputStream ваше «хранилище доверия» и pwd пароль, который вы использовали для его шифрования. TrustManager Для реализации по умолчанию, которую это дает вам, требуется только набор доверенных сертификатов для работы, об остальном позаботятся за вас.