Microsoft 社는 2022년 6월 15일 Internet Explorer 11의 지원을 종료했습니다.

이메일 서버에 SSL 로 접속할 때, 인증서 오류를 무시하는 방법

제목

이메일 서버에 SSL 로 접속할 때, 인증서 오류를 무시하는 방법

1. 개요

1.1. 에러 메시지

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

1.2. 원인

SSL 방식으로 이메일 서버에 접속을 시도하는데, 서버쪽 인증서를 신뢰할 수 없을 때 발생하는 오류이다.

  • Let's Encrypt 와 같이 클라이언트에서 알지 못하는 인증기관에서 인증서를 발급받은 경우(클라이언트 쪽 Java 의 신뢰하는 인증기관 인증서 목록(keystore)에 없는 경우)
  • 서버 인증서의 기간이 만료된 경우
  • 인증기관을 통하지 않고 스스로 인증서를 발급한 경우
  • 서버이름과 인증기관에서 발급한 인증서의 호스트가 다른 경우
  • 기타 상상력이 필요한 경우

첫 번째 것은 처리 방법을 찾을 필요가 있다.

1.3. 해결방안

인터넷에 떠도는 2가지 방법이 있다(원저자를 정확히 알기는 힘들다).

  • 서버 인증서를 클라이언트로 다운받아 설치하는 방법
  • TrustManager를 구현하여 서버쪽 인증서의 신뢰여부를 검사하지 않도록 하는 방법

첫 번째는 InstallCert.java 라는 파일을 이용한 방법이고, 안전한 방법이라고 할 수 있으나, 대체로 적절한 방법이 아닐 가능성이 높다.

두 번째는 서버 인증서를 신뢰할 수 없다면, 서버도 신뢰할 수 없기 때문에, 안전한 방법이라고는 할 수 없으나, 널리 알려진 해결책이다.

두 번째는 HttpURLConnection 에서 유례된 것으로 생각되는데, 여기서는 TrustManager 따위를 구현하는 것보다 간이한 방법에 대해 소개하려고 한다.

여기서 소개한 방법도 안전한 방법이라고 할 수 없으나, TrustManager 따위를 구현할 요량이라면, 검토할 가치가 있다.

1.4. 참고자료

다음에서 아래 쪽의 Properties 항목을 참조한다.

2. 이메일 서버에 SSL 로 접속할 때, 인증서 오류를 무시하는 방법

여기서 소개하는 방법은 다음과 같이 신뢰할 수 있는 host 를 전체(*)로 설정하는 방법이다.

java.util.Properties props = new java.util.Properties();
props.setProperty("mail.pop3.ssl.trust", "*");
javax.mail.Session session = javax.mail.Session.getInstance(props, null);

imap 은 다음과 같다.

props.setProperty("mail.imap.ssl.trust", "*");

smtp 는 다음과 같다.

props.setProperty("mail.smtps.ssl.trust", "*");

3. 전체 소스

3.1. pop3 혹은 imap

FetchMailProcessorImpl.java 에서 pop3/imap 에 연결하는 부분만 떼어낸 소스코드이다.

String type = "pop3";
//String type = "imap";
String host = "";
int port = 0;
String userName = "";
String password = "";
String encryptionType = "STARTTLS";
//String encryptionType = "SSL/TSL";
java.util.Properties props = new java.util.Properties();
props.setProperty("mail.store.protocol", type);
if(type.equals("pop3")) {
props.setProperty("mail.pop3.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.setProperty("mail.pop3.socketFactory.fallback", "false");
props.setProperty("mail.pop3.socketFactory.port", Integer.toString(port));
props.setProperty("mail.pop3.ssl.trust", "*");
props.setProperty("mail.pop3.port", Integer.toString(port));
} else if(type.equals("imap")) {
props.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.setProperty("mail.imap.socketFactory.fallback", "false");
props.setProperty("mail.imap.socketFactory.port", Integer.toString(port));
props.setProperty("mail.imap.ssl.trust", "*");
if(encryptionType.equals("STARTTLS")) {
props.setProperty("mail.imap.starttls.enable", "true");
} else if(encryptionType.equals("SSL/TSL")) {
props.setProperty("mail.imap.ssl.enable", "true");
}
props.setProperty("mail.imap.fetchsize", Integer.toString(1024 *1024));
props.setProperty("mail.imap.port", Integer.toString(port));
}
javax.mail.URLName urln = new javax.mail.URLName(
type,
host,
port,
null,
userName,
password
);
javax.mail.Session session = javax.mail.Session.getInstance(props, null);
try {
javax.mail.Store store = session.getStore(urln);
/*
store.connect();
store.close();
*/
} catch (javax.mail.NoSuchProviderException e) {
}

3.2. smtp

MailSendProcessorImpl.java 에서 smtps 에 연결하는 부분만 떼어낸 소스코드이다.

String type = "smtps";
String host = "";
int port = 0;
String userName = "";
String password = "";
String encryptionType = "STARTTLS";
//String encryptionType = "SSL/TSL";
java.util.Properties props = new java.util.Properties();
props.setProperty("mail.smtps.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.setProperty("mail.smtps.socketFactory.fallback", "false");
props.setProperty("mail.smtps.socketFactory.port", Integer.toString(port));
props.setProperty("mail.smtps.ssl.trust", "*");
if(encryptionType.equals("STARTTLS")) {
props.setProperty("mail.smtps.starttls.enable", "true");
} else if(encryptionType.equals("SSL/TSL")) {
props.setProperty("mail.smtps.ssl.enable", "true");
}
props.setProperty("mail.smtps.port", Integer.toString(port));
javax.mail.URLName urln = new javax.mail.URLName(
type,
host,
port,
null,
userName,
password
);
javax.mail.Session session = javax.mail.Session.getInstance(props, null);
javax.mail.Transport transport = new com.sun.mail.smtp.SMTPTransport(session, urln);
//transport.connect();
//transport.close();
제목

첨부파일