Расслабляющий алгоритм SSL ограничивает программно - PullRequest
0 голосов
/ 31 августа 2018

проблема

Я пытаюсь подключиться к локальному серверу через сокет SSL. Сервер использует сертификат SSL, который:

  1. Самоподписан.
  2. Имеет подпись MD5 с RSA (?)

Я знаю о последствиях для безопасности, но по независящим от меня причинам я не могу изменить или запросить изменения в этом сертификате, поэтому я вынужден работать с ним - или, скорее, с ним.

Чтобы преодолеть два вышеуказанных момента, я создал:

  1. A TrustManager, разрешающий все сертификаты.
  2. AlgorithmConstraints, который разрешает все алгоритмы.

Я получаю следующую ошибку:

Caused by: java.security.cert.CertPathValidatorException: Algorithm constraints check failed on signature algorithm: MD5withRSA

Кажется, что мой подход к ослаблению ограничений алгоритма неверен.

Примечание : я знаю, что алгоритм MD5withRSA можно разрешить путем изменения конфигурации JVM или параметра командной строки, но мне нужно сделать это программно.

код

TrustManager был создан следующим образом:

TrustManager[] trustManager = new TrustManager[] { 
    new X509TrustManager() {     
        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
            return new X509Certificate[0];
        } 
        @Override
        public void checkClientTrusted( 
            java.security.cert.X509Certificate[] certs, String authType) {
            } 
        @Override
        public void checkServerTrusted( 
            java.security.cert.X509Certificate[] certs, String authType) {
        }
    } 
};

AlgorithmConstraints был создан следующим образом:

AlgorithmConstraints algorithmConstraints = new AlgorithmConstraints() {
    @Override
    public boolean permits(Set<CryptoPrimitive> primitives, String algorithm, AlgorithmParameters parameters) {
        return true;
    }

    @Override
    public boolean permits(Set<CryptoPrimitive> primitives, Key key) {
        return true;
    }

    @Override
    public boolean permits(Set<CryptoPrimitive> primitives, String algorithm, Key key, AlgorithmParameters parameters) {
        return true;
    }
}

И, наконец, код сокета выглядит следующим образом:

SSLContext sslContext = SSLContext.getInstance("TLS"); 

sslContext.init(null, trustManager, new java.security.SecureRandom());

SSLSocketFactory factory = sslContext.getSocketFactory();
SSLSocket sslsocket = (SSLSocket) factory.createSocket(server, port);

SSLParameters sslParameters = new SSLParameters();
sslParameters.setAlgorithmConstraints(algorithmConstraints);

sslsocket.setSSLParameters(sslParameters);

sslSocket.startHandshake();

Предложения

Ответы [ 2 ]

0 голосов
/ 04 сентября 2018

Раствор

Как отмечалось в этом ответе , нужно использовать X509ExtendedTrustManager вместо X509TrustManager. Это также устраняет необходимость в пользовательской реализации AlgorithmConstraints, как я сделал в этом вопросе.

Предупреждение

Для тех, кто находит / использует это решение:

Обратите внимание, что обход стандартной проверки сертификата подвергает соединение (и, соответственно, приложение) ряду угроз безопасности, ни один из которых не является незначительным!

Обязательно реализуйте по крайней мере некоторые дополнительные проверки безопасности, такие как закрепление сертификата , или по крайней мере на 100% убедитесь, что приложение используется в доверенной среде!

0 голосов
/ 01 сентября 2018

Похоже, что некоторые алгоритмы по умолчанию отключены в файлах свойств JAVA_HOME/lib/jre/security/java.security, включая MD5. В частности, два свойства безопасности jdk.tls.disabledAlgorithms и jdk.certpath.disabledAlgorithms представляются критическими.

Спасибо dave_thompson_085 за исправление моей путаницы в свойствах системы и свойствах безопасности. Просто используя метод Security.setProperty(), я смог подключиться к серверу SSL, используя сертификат, подписанный с помощью MD5WithRSA. Я копирую значения двух свойств безопасности из файла JAVA_HOME/lib/security/java.security и удаляю MD5 из отключенных алгоритмов, которые затем называются Security.setProperty() с измененным списком. На моем JDK значения этих свойств были:

jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 1024, \
    EC keySize < 224, DES40_CBC, RC4_40, 3DES_EDE_CBC

jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \
    RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224

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

Security.setProperty("jdk.tls.disabledAlgorithms", "SSLv3, RC4, DH keySize < 1024, EC keySize < 224, DES40_CBC, RC4_40, 3DES_EDE_CBC");
Security.setProperty("jdk.certpath.disabledAlgorithms", "MD2, SHA1 jdkCA & usage TLSServer, RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224");

Обратите внимание, что это, конечно, оставляет вас уязвимыми для MD5. Вы хотите, чтобы они были доступны только для одного самозаверяющего сертификата, но теперь вы должны самостоятельно выполнить всю работу по запрету MD5 везде в TLS.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...