Проверка сертификатов X509 с использованием Java APis

Я пытаюсь проверить сертификат на хранилище ключей Java, и это код, который я использую, как показано ниже. Если он завершится успешно, я предполагаю, что проверка прошла правильно, иначе, если вызывается исключение, то проверка не выполняется. Меня беспокоит:

Достаточно ли кода, достаточного для проверки сертификата? Как и в том, что здесь что-то мне не хватает (например, проверяя данные, подписанные компьютером, отправив мне сертификат?)? 2. Следует ли проверять подпись, содержащуюся в сертификате? Если да, то как?

Заранее благодарим за ответ! Прадип

// To check the validity of the dates
cert.checkValidity();
//Check the chain
CertificateFactory cf = CertificateFactory.getInstance("X.509");
List<X509Certificate> mylist = new ArrayList<X509Certificate>();          
mylist.add(cert);
CertPath cp = cf.generateCertPath(mylist);
PKIXParameters params = new PKIXParameters(getTrustStore());
params.setRevocationEnabled(false);
CertPathValidator cpv =
      CertPathValidator.getInstance(CertPathValidator.getDefaultType());
PKIXCertPathValidatorResult pkixCertPathValidatorResult =
      (PKIXCertPathValidatorResult) cpv.validate(cp, params);

Ответы

Ответ 1

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

Вы должны добавить все промежуточные сертификаты, чтобы сформировать целую цепочку.

Чтобы убедиться, что сертификат по-прежнему действителен, вы не должны отключать проверки отзыва. Если вы не хотите получать CRL (который может быть большим), эмитент может предлагать поддержку OCSP. Но это должно быть включено в среде выполнения Java, задав некоторые свойства системы.

Если средство проверки пути успешно возвращается, вам не нужно ничего проверять. Если сертификат недействителен, будет создано исключение.

Кроме того, явная проверка даты действия не нужна. Это происходит во время проверки (используя текущее время, если вы не укажете время через PKIXParameters).


Для более подробного обсуждения валидации, включая пример кода см. предыдущий мой ответ.

Ответ 2

Если вы довольны настройками доверия по умолчанию (поскольку они будут использоваться для стандартного SSLContext), вы можете создать X509TrustManager независимо от SSL/TLS и использовать, если для подтверждения своего сертификата самостоятельно.

Это будет выглядеть так:

TrustManagerFactory trustManagerFactory =
    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore)null);
// you could use a non-default KeyStore as your truststore too, instead of null.

for (TrustManager trustManager: trustManagerFactory.getTrustManagers()) {  
    if (trustManager instanceof X509TrustManager) {  
        X509TrustManager x509TrustManager = (X509TrustManager)trustManager;  
        x509TrustManager.checkServerTrusted(...);
    }  
}

(Вы также должны проверить идентификатор сервера и совпадение сертификата, см. RFC 6125 (Представление и проверка идентификации службы на основе доменных приложений в инфраструктуре открытого ключа Интернета Использование сертификатов X.509 (PKIX) в контексте безопасности транспортного уровня (TLS).)

Ответ 3

Что вы здесь делаете, это проверка того, был ли подписан сертификат (в вашем примере cert) (напрямую) любым доверенным центром сертификации в доверенном магазине.
Кроме того, вы проверяете срок действия, но проверка отзыва не выполняется.
Поэтому, если cert не был подписан никаким доверенным ЦС, вы получите исключение.
Таким образом, кода достаточно, чтобы проверить, была ли cert подписана любым доверенным ЦС


Если вы ссылаетесь на аутентификацию сервера, тогда кода в сообщении недостаточно.
Этот код просто проверяет, что специальный сертификат подписывается доверенным ЦС.
У вас нет указаний, хотя если "сущность", которая отправляет вам этот сертификат, фактически является владельцем сертификата (то есть у них есть закрытый ключ, связанный с этим сертификатом).
Это часть аутентификации SSL, где, например, клиент отправляет сообщение ClientKeyExchange, зашифрованное открытым ключом удаленного сервера, и уверен, что если другая сторона является фальшивой, тогда невозможно будет расшифровать сообщение