Рассмотрим следующий пример кода, который использует TrustManager
для входа используется ли исходящее соединение действительный сертификат (но принять соединение во всех случаях):Как проверить, является ли сертификат сертификатом EV с Java?
import java.security.*;
import java.security.cert.*;
import javax.net.ssl.*;
public class CertChecker implements X509TrustManager {
private final X509TrustManager defaultTM;
public CertChecker() throws GeneralSecurityException {
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init((KeyStore)null);
defaultTM = (X509TrustManager) tmf.getTrustManagers()[0];
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
if (defaultTM != null) {
try {
defaultTM.checkServerTrusted(certs, authType);
System.out.println("Certificate valid");
} catch (CertificateException ex) {
System.out.println("Certificate invalid: " + ex.getMessage());
}
}
}
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
public X509Certificate[] getAcceptedIssuers() { return null;}
public static void main(String[] args) throws Exception {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[] {new CertChecker()}, new SecureRandom());
SSLSocketFactory ssf = (SSLSocketFactory) sc.getSocketFactory();
((SSLSocket)ssf.createSocket(args[0], 443)).startHandshake();
}
}
Что я должен сделать внутри метода checkClientTrusted
проверить если этот сертификат является расширенным сертификатом проверки (зеленая адресная строка в современных браузерах) или обычная (желтая адресная строка)?
редактировать:
Я пытаюсь получить CertPathValidator
работы, но почему-то я только получаю исключение о сертификате не является сертификат CA ... Есть идеи?
edit2: Использование PKIXParameters
вместо PKIXBuilderParameters
private boolean isEVCertificate(X509Certificate[] certs, String authType) {
try {
CertPath cp = new X509CertPath(Arrays.asList(certs));
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(new File(System.getProperty("java.home"), "lib/security/cacerts")), null);
PKIXParameters cpp = new PKIXParameters(ks);
cpp.setRevocationEnabled(false);
CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
PKIXCertPathValidatorResult res = (PKIXCertPathValidatorResult) cpv.validate(cp, cpp);
System.out.println(res.getTrustAnchor().getCAName());
System.out.println(res.getPolicyTree().getValidPolicy());
System.out.println(cp);
return false;
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
}
Я тестирую против реальных сертификатов EV. Код теперь работает с www.paypal.com
(в том смысле, что он не генерирует исключение), но не работает с banking.dkb.de
. :-(
Но даже с Paypal.com доверие якорь getCAName возвращает нуль, так как я могу знать, против которой CA было подтверждено, так что я могу смотреть на правильную политику EV?
Ваш код валидатора несколько отличается тем, что вы используете 'PKIXBuilderParameters' для проверки; обычно я бы использовал только «PKIXParameters» (цель уже известна). Кроме того, используется ли цепочка сертификатов, выданных через «настоящий» ЦС, или тестовую, которую вы подписали? Если последнее, я буду обеспокоен различными расширениями. Они могут быть очень сложными, чтобы получить право, чтобы они удовлетворяли валидатору PKIX. – erickson
обновил мой вопрос соответственно ... – mihi
Хорошо, посмотрите мой пример. Он работает для 'https: // banking.dkb.de/dkb /'. – erickson