Проверка сертификата X.509 с использованием Java и Bouncycastle - PullRequest
18 голосов
/ 16 марта 2010

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

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

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

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

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

Ответы [ 2 ]

32 голосов
/ 17 марта 2010

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

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

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

/* 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);

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

9 голосов
/ 16 марта 2010

Хорошо, идея CA заключается в следующем:

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

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

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

...