Подтвердить что ты не робот

X.509 Проверка сертификата с помощью Java и Bouncycastle

через wiki-страница bouncycastle Я смог понять, как создать корневой сертификат X.509 и запрос на сертификацию, но я не вполне понимают, как последовать за концепцией и программированием.

Предположим, что сторона A выполняет запрос сертификата и получает свой сертификат клиента из CA. Как может какая-либо сторона B проверить сертификат? Какой сертификат нужен? Корневой сертификат? "Нормальный" клиентский сертификат?

И как валидация работает на уровне программирования, если мы предположим, что A успешно отправил свой сертификат в формате DER или PEM в B?

Любая помощь очень ценится.

С наилучшими пожеланиями, Rob

4b9b3361

Ответ 1

С точки зрения программиста вам нужно несколько вещей, чтобы проверить сертификат X.509.

  • Набор "доверительных привязок" - корневые сертификаты центров сертификации, на которые вы полагаетесь. Они должны быть защищены от несанкционированного доступа, чтобы злоумышленник не заменил сертификат ЦС своей собственной подделкой. Открытые ключи в этих сертификатах используются для проверки цифровых подписей на других сертификатах.
  • Коллекция промежуточных сертификатов. Приложение может хранить их, но большинство протоколов, таких как SSL и S/MIME, которые используют сертификаты, имеют стандартный способ предоставления дополнительных сертификатов. Хранение их не требует особого ухода; их целостность защищена сигнатурой корневого ЦС.
  • Информация об отзыве. Даже если сертификат был выпущен ЦС, он мог быть отозван преждевременно, поскольку был раскрыт секретный ключ, или конечный объект изменил свою личность. (Например, человек переключает задания и сертификат с их старым именем компании в нем отменяется.) CRL или веб-сервис, такой как OCSP, могут использоваться для получения обновления о статусе сертификата.

С этими доступными входами вы можете использовать встроенную поддержку PKIX для создания и проверки пути сертификата.

/* Givens. */
InputStream trustStoreInput = ...
char[] password = ...
List<X509Certificate> chain = ...
Collection<X509CRL> crls = ...

/* Construct a valid path. */
KeyStore anchors = KeyStore.getInstance(KeyStore.getDefaultType());
anchors.load(trustStoreInput, password);
X509CertSelector target = new X509CertSelector();
target.setCertificate(chain.get(0));
PKIXBuilderParameters params = new PKIXBuilderParameters(anchors, target);
CertStoreParameters intermediates = new CollectionCertStoreParameters(chain)
params.addCertStore(CertStore.getInstance("Collection", intermediates));
CertStoreParameters revoked = new CollectionCertStoreParameters(crls);
params.addCertStore(CertStore.getInstance("Collection", revoked));
CertPathBuilder builder = CertPathBuilder.getInstance("PKIX");
/* 
 * If build() returns successfully, the certificate is valid. More details 
 * about the valid path can be obtained through the PKIXBuilderResult.
 * If no valid path can be found, a CertPathBuilderException is thrown.
 */
PKIXBuilderResult r = (PKIXBuilderResult) builder.build(params);

Важно отметить, что если путь не может быть найден, вы не получите много информации о причине. Это может расстраивать, но это так по дизайну. В общем, существует много потенциальных путей. Если все они не работают по разным причинам, как разработчик путей может решить, что сообщить в качестве причины?

Ответ 2

Хорошо, идея CAs такова:

  • ЦС - это люди, которым все доверяют. Для этого в вашем браузере/почтовом клиенте/даже на моем мобильном телефоне доступен выбор доверенных ЦС. В вашем случае ваш общедоступный корневой ключ (сертификат) должен быть в вашем приложении.
  • Пользователи отправляют запросы в ЦС для сертификата в формате PEM с открытым ключом. CA делают некоторые (я оставляю эту двусмысленную преднамеренную) форму проверки конечного пользователя, например, взимают их деньги или в случае расширенных проверок (зеленых) сертификатов, проверки фона.
  • Если CA не считает запрос пользователя действительным, они сообщают об этом как-то.
  • Если они это сделают, они подписывают открытый ключ и создают сертификат, содержащий эту информацию. Здесь вы обрабатываете cert-req и превращаете его в сертификат X.509.
  • Другие пользователи сталкиваются с нашим фиктивным пользователем и хотят знать, могут ли они доверять им. Таким образом, они заглядывают в сертификат и обнаруживают, что он подписан цифровой подписью кем-то, у кого есть в своем списке доверия. Таким образом, тот факт, что они доверяют корневому ЦС и только корневому ЦС, может подписывать (через свой закрытый ключ) этот открытый ключ пользователя, а ЦС доверяет пользователю, мы выводим, что новый пользователь может доверять mr фиктивный.

На программном уровне вы реализуете это, читая сертификат X.509 и определяя, кем должен быть CA. Учитывая этот отпечаток CA, вы найдете его в своей базе данных и проверьте подпись. Если он соответствует, у вас есть цепочка доверия.

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