2009-08-02 3 views
17

javax.mail API를 사용하여 메일을 보내는 SSL 클라이언트를 작성하려고합니다. 내가 가지고있는 문제는 서버에서 SSL을 사용하도록 요청하지만 서버가 비표준 SSL 인증서로도 구성되어 있다는 것입니다. 발견 한 웹 페이지는 인증서를 트러스트 스토어에 설치해야한다고 말합니다. 나는 그것을하고 싶지 않다. (나는 필요한 권한이 없다.)자바가 "트러스트 스토어"를 무시하고 그것이 얻은 SSL 인증서를 수령 할 수 있습니까?

  1. Java가 인증서 오류를 무시하고 받아들이게하는 방법이 있습니까?
  2. 트러스트 저장소를 내 프로그램에 대해 로컬로 유지하고 전체 JVM에 설치하지 않는 방법이 있습니까?
+0

그냥 명확히하기 위해 서버 코드를 변경하거나 클라이언트 만 변경할 수 있습니까? –

+0

인증서 확인 단계를 무시하면 안 좋은 생각입니다. 당신이 처음에 누구인지 확실하게 밝히지 않았다면 누군가에게 비밀리에 이야기하는 것이 거의 없습니다. 옵션 2 (로컬 신뢰 저장소)는 사용하기 쉽습니다. – Bruno

+1

일부 상황에서는 인증 단계가 무시됩니다. 예를 들어, 격리 된 네트워크에서 SSL이 정책으로 인해 유일하게 활성화 된 서비스이지만 관리자가 비 SSL 서비스를 활성화하는 방법을 모르기 때문에 . – vy32

답변

16

모든 인증서를 허용하는 가짜 TrustManager를 만들어서 매니저. 다음과 같은 것 :

public class MyManager implements com.sun.net.ssl.X509TrustManager { 
    public boolean isClientTrusted(X509Certificate[] chain) { return true; } 
    public boolean isHostTrusted(X509Certificate[] chain) { return true; } 
    ... 
} 


com.sun.net.ssl.TrustManager[] managers = 
    new com.sun.net.ssl.TrustManager[] {new MyManager()}; 

com.sun.net.ssl.SSLContext.getInstance("SSL"). 
     .init(null, managers, new SecureRandom()); 
+6

숨겨진 'com.sun. *'클래스를 조정하는 대신 JSSE 공용 API를 사용하여이 작업을 수행해야합니다. (so_mv 대답을 참조하십시오.) – Bruno

6

(질문 2 답)이 시도 :

System.setProperty("javax.net.ssl.trustStore", "/path/to/truststore"); 
또한 추가 명령 줄 매개 변수로이를 지정할 수 있습니다

: 페도라에

java -Djavax.net.ssl.trustStore=/path/to/truststore <remaining arguments> 

이 시스템 전체 자바 될 수있다 트러스트 스토어 /etc/pki/java/cacerts

+1

거기에 * 등을 사용하는 것처럼 두 번째 인수로 "모두 신뢰"를 지정하는 방법이 있습니까? –

+0

@UmerHayat 아니요. 다른 두 개의 대답과 같이 코드를 작성해야합니다. –

21

# 1의 작업 코드 (jdk1.6.0_23).

수입

import javax.net.ssl.HttpsURLConnection; 
import javax.net.ssl.SSLContext; 
import javax.net.ssl.TrustManager; 
import javax.net.ssl.X509TrustManager; 
import java.security.cert.X509Certificate; 

실제 신뢰 모두의 TrustManager 코드를.

TrustManager trm = new X509TrustManager() { 
    public X509Certificate[] getAcceptedIssuers() { 
     return null; 
    } 

    public void checkClientTrusted(X509Certificate[] certs, String authType) { 

    } 

    public void checkServerTrusted(X509Certificate[] certs, String authType) { 
    } 
}; 

SSLContext sc = SSLContext.getInstance("SSL"); 
sc.init(null, new TrustManager[] { trm }, null); 
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); 
+0

감사합니다. 이것에 대한 유일한 문제점은 모든 certs를 신뢰하도록 설정을 전역 적으로 설정한다는 것입니다. 안전한 접근은 URLConnection을 HttpsURLConnection로 다시 캐스팅하고 setSSLSocketFactory를 호출하는 것입니다.그럼에도 불구하고 이것은 대단한 대답입니다. 다른 몇몇 사람들은 신뢰 확인을 무시하는 것이 불가능하다고 말했고 인증서를 추가하거나 JVM 옵션을 조정해야했습니다. – Cervo

+4

호스트 이름이 인증서와 일치하지 않을 경우를 대비하여이 작업이 필요할 수도 있습니다. 의 HostnameVerifier nullVerifier = 새의 HostnameVerifier() { @Override 공공 부울 확인 (문자열 호스트 이름, SSLSession에 세션) { 반환 사실; } }; HttpsURLConnection.setDefaultHostnameVerifier (nullVerifier); – seanf

1

그냥 VM 인수에 -Dtrust_all_cert=true를 추가합니다. 이 인수는 java가 모든 인증서 검사를 무시하도록합니다.

+0

그것은 꽤 무서운데, 좋은 대답 인 것 같습니다! 나는 자바 내에서 그것을하고 싶습니다, 그리고 아마도 앞으로 좀 더 제어 할 수 있습니다. – vy32

+6

VM 인수가 아니기 때문에 일반적으로 작동하지 않습니다. –

-2

CLI에서 -noCertificationCheck 인자를 java에 추가하여 인증서 검사를 무시할 수 있습니다.

관련 문제