Büyük Java uygulamamıza eklediğim bir modül, başka bir şirketin SSL güvenli web sitesiyle sohbet etmek zorunda. Sorun, sitenin kendinden imzalı bir sertifika kullanmasıdır. Ortadaki bir adamla karşılaşmadığımı doğrulamak için sertifikanın bir kopyası var ve sunucuya bağlantı başarılı olacak şekilde bu sertifikayı kodumuza dahil etmem gerekiyor.
Temel kod şöyledir:
void sendRequest(String dataPacket) {
String urlStr = "https://host.example.com/";
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setMethod("POST");
conn.setRequestProperty("Content-Length", data.length());
conn.setDoOutput(true);
OutputStreamWriter o = new OutputStreamWriter(conn.getOutputStream());
o.write(data);
o.flush();
}
Kendinden imzalı sertifika için herhangi bir ek işlem yapılmadan bu durum conn.getOutputStream () öğesinde aşağıdaki istisna dışında ölür:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
....
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
....
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
İdeal olarak, kodumun Java'ya bu kendinden imzalı sertifikayı, uygulamadaki bu nokta için ve başka hiçbir yerde kabul etmesini öğretmesi gerekiyor.
Sertifikayı JRE'nin sertifika yetkilisi deposuna aktarabileceğimi biliyorum, bu da Java'nın kabul etmesine izin verecek. Bu yardımcı olabilirsem almak istediğim bir yaklaşım değil; tüm müşterilerimizin makinelerinde kullanamayacakları bir modül için çok invaziv görünüyor; aynı JRE'yi kullanan diğer tüm Java uygulamalarını etkileyecektir ve bu siteye erişen başka herhangi bir Java uygulamasının olasılığı sıfır olsa bile bunu sevmiyorum. Ayrıca önemsiz bir işlem değil: UNIX'te JRE'yi bu şekilde değiştirmek için erişim hakları elde etmeliyim.
Ayrıca bazı özel kontrol yapan bir TrustManager örneği oluşturabildiğimi gördüm. Hatta bu sertifika dışındaki tüm durumlarda gerçek TrustManager'a yetki veren bir TrustManager bile oluşturabilirim. Ancak TrustManager'ın global olarak yüklendiği anlaşılıyor ve başvurumuzdaki diğer tüm bağlantıları etkileyeceğini düşünüyorum ve bu da benim için oldukça doğru kokmuyor.
Kendinden imzalı bir sertifikayı kabul etmek için bir Java uygulaması kurmanın tercih edilen, standart veya en iyi yolu nedir? Yukarıda aklımdaki tüm hedeflere ulaşabilir miyim yoksa uzlaşmak zorunda mıyım? Dosya ve dizinleri, yapılandırma ayarlarını ve çok az kod içeren bir seçenek var mı?