HHeLiBeXの日記 正道編

日々の記憶の記録とメモ‥

SSLサーバー証明書を無視するための対応方法

よりにもよって繁忙期に、以下のROOT証明書期限切れで接続不可になるというトラブルに見舞われ、なんじゃゴルァ!と叫びながら対応した記憶の記録。

状況としては、WinSCPだと(証明書のCNがホスト名と違うってエラーが出るけど(ボソッ))接続できるが、Javaプログラムやlftpコマンドだと証明書の期限切れだと怒られる事案。

ひとまず、以下の情報を頼りに証明書チェインの情報を取ってみた。

$ openssl s_client -connect xxxxx.com:21 -starttls ftp -showcerts < /dev/null > hoge.txt
  hoge.txt の中にある証明書4つを分割して別ファイルに保存
$ openssl x509 -text -in 3.txt -noout
  :
        Validity
            Not Before: May 30 10:48:38 2000 GMT
            Not After : May 30 10:48:38 2020 GMT
        Subject: C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust RSA Certification Authority
  :
$ openssl x509 -text -in 4.txt -noout
  :
        Validity
            Not Before: May 30 10:48:38 2000 GMT
            Not After : May 30 10:48:38 2020 GMT
        Subject: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root
  :

はい、というわけで。

使い古されているけどすぐに忘れてしまうコード断片のメモ。

FTPSClientの場合

import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.net.ftp.FTPSClient;

public class Main {
    public static void main(String[] args) {
        FTPSClient client = new FTPSClient("TLS", false);
        TrustManager tm = new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }
            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }
        };
        client.setTrustManager(tm);

        try {
            client.connect("example.com", 21);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

HttpsURLConnectionの場合

ついでに。

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class Mail {
    public static void main(String[] args) {
        TrustManager[] tm = { new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }

            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }
        } };
        try {
            SSLContext sslcontext = SSLContext.getInstance("SSL");
            sslcontext.init(null, tm, null);
    
            URL connectUrl = new URL("https://exaple.com/");
            HttpsURLConnection urlconn = (HttpsURLConnection) connectUrl.openConnection();
            urlconn.setSSLSocketFactory(sslcontext.getSocketFactory());
    
            urlconn.connect();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

lftpコマンドの場合

さらについで。 冒頭の方のサイトに書いてあるけど。

$ lftp -u uuuu,pppp -e 'set ssl:verify-certificate no' example.com