Частичная проверка цепочки на Java SSL TrustManager

У меня есть требование, согласно которому можно предоставить промежуточный ЦС, которому можно доверять, но не ЦС, которые его подписали. И, используя это как хранилище доверия, я хотел бы иметь возможность доверять серверу SSL, у которого есть сертификат, подписанный этим промежуточным центром сертификации. Реализация по умолчанию предполагает построение всей цепочки до тех пор, пока не будет найден доверенный самозаверяющий корневой ЦС. Я считаю, что на этом основана вся платформа X509. Но по определенным причинам я могу предоставить только промежуточный ЦС.

Код представляет собой обычное создание SSLContext:

    // keystore part is pseudocode to make a point
    KeyStore keyStore = someWayToGenerateKeyStore;
    keyStore.add(intermediateCa);
    //keyStore.add(rootCaThatSignedTheIntermediateCaAbove); it will work if I add this. But I don't want to for reasons.

    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
    tmf.init(keyStore);
    SSLContext ctx = SSLContext.getInstance("TLSv1.2");
    ctx.init(new KeyManager[], tmf.getTrustManagers(), new SecureRandom());
    SslContextFactory sslContextFactory = new SslContextFactory();
    sslContextFactory.setSslContext(ctx);
    client = new WebSocketClient(sslContextFactory);

OpenSSL имеет для этого параметр, который, кажется, работает. Так что я думаю, что это не совсем неортодоксальный подход.

openssl verify -CApath /dev/null -partial_chain -trusted g1 g0

Есть две причины для требования иметь только промежуточный ЦС в хранилище доверенных сертификатов.

  • Это упрощает передачу одного доверенного сертификата по системе, которая в настоящее время зависит от одного самозаверяющего сертификата ЦС. Для связи и настройки многих компонентов на данный момент требуется один сертификат, и его изменение потребует значительного рефакторинга.
  • Мы хотим убедиться, что доверяем только сертификату, подписанному данным промежуточным сертификатом ЦС. Если мы добавим другие сертификаты ЦС в цепочке в хранилище доверенных сертификатов, реализация SSL будет доверять любому сертификату, подписанному другими ЦС, которых мы также хотим избежать. Вероятно, есть и другие способы сделать это, например, проверить issuer_dn, но я хотел бы изучить другие подходы.

person Natan    schedule 17.05.2018    source источник


Ответы (1)


Реализация по умолчанию предполагает построение всей цепочки до тех пор, пока не будет найден доверенный самозаверяющий корневой ЦС.

Нет, это не так. Это проверка всей цепочки до тех пор, пока в вашем хранилище доверенных сертификатов не будет найден доверенный сертификат подписи. «Самоподписанный» не имеет к этому никакого отношения, а «доверенный… корневой ЦС» означает не что иное, как то, что он присутствует в вашем хранилище доверенных сертификатов.

Поэтому все, что вам нужно сделать, это добавить этот сертификат в ваше хранилище доверенных сертификатов. Вам вообще не нужно писать код.

Но почему вы хотите доверять промежуточной подписывающей стороне, не доверяя корневой, — загадка.

person user207421    schedule 17.05.2018
comment
Извините, я немного запутался в вашем ответе из-за терминов, которые могут означать разные вещи. Вы говорите, что это должно работать, пока у меня есть промежуточный ЦС в хранилище доверенных сертификатов, но не ЦС, подписавший этот промежуточный ЦС? Это не было моим опытом, и это не поведение OpenSSL, если только вы не передадите -partial_chain в качестве параметра. Я отредактирую свой вопрос, чтобы объяснить тайну. - person Natan; 17.05.2018
comment
1. Ваш вопрос касается Java, а не OpenSSL. 2. Вы совершаете слишком распространенную ошибку, смешивая аутентификацию с авторизацией. Вы должны доверять любому сертификату, подписанному признанным ЦС, но авторизуете ли вы идентификацию, установленную этим сертификатом для вашего приложения, — это совершенно другой вопрос. . Сертификат предназначен для идентификации, а не для авторизации. - person user207421; 17.05.2018
comment
1. Я протестировал Java-аналог, и только добавление промежуточного ЦС в хранилище доверия не работает по умолчанию. Отсюда вопрос. Если вы уверены, что это должно работать, я буду отлаживать больше и искать другие проблемы в своем тесте. Я использовал OpenSSL в качестве аргумента подкрепления, так как это очень важная реализация в среде x509. 2. Отмечено. Я ценю вклад. - person Natan; 17.05.2018