Androidのトラストマネージャーを上書きしようとしています。基になるトラストマネージャーに証明書をチェックさせたいのですが、証明書の有効期限が切れているかどうかを判断する必要があります。証明書の有効期限が切れている場合は、それを無視して証明書を受け入れる必要があります。一部のモバイルデバイスでは、バッテリーを取り外すと日付が古い日付にリセットされ、証明書の有効期限が切れたように見えます。これが発生した場合でも、アプリは実行を継続する必要があります。
私が抱えている問題は、このコード行がNullPointerExceptionをスローすることです。
origTrustmanager.checkServerTrusted(certs, authType);
ドキュメントによると、checkServerTrustedは決してNullPointerExeptionをスローするべきではありません。certsには2つのアイテムが含まれています。authTypeは「RSA」に設定されています。カスタムのTrustManagerを実装しない場合、証明書の有効期限が切れたことを明確に示す例外がスローされるため、基盤となるTrustManagerがその役割を果たしていることがわかります。デバイスの日付と時刻を証明書の有効期間内に設定した場合でも、上記のcheckServerTrusted行で例外が生成されます。なんで?明らかに私は何か間違ったことをしている。カスタムTrustManagerのコードと、URLにアクセスする方法は次のとおりです。
class SSLTrustManager
{
private X509TrustManager origTrustmanager;
public SSLTrustManager()
{
try
{
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init((KeyStore) null);
TrustManager[] trustManagers = tmf.getTrustManagers();
this.origTrustmanager = (X509TrustManager) trustManagers[0];
}
catch (Exception ex)
{
}
}
public javax.net.ssl.SSLSocketFactory GetSocketFactory()
{
try
{
TrustManager[] wrappedTrustManagers = new TrustManager[] {
new X509TrustManager()
{
public java.security.cert.X509Certificate[] getAcceptedIssuers()
{
return origTrustmanager.getAcceptedIssuers();
}
public void checkClientTrusted(X509Certificate[] certs, String authType)
{
try
{
origTrustmanager.checkClientTrusted(certs, authType);
}
catch (CertificateException e)
{
}
}
public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException
{
try
{
origTrustmanager.checkServerTrusted(certs, authType);
}
catch(Exception ex)
{
}
}
}
};
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, wrappedTrustManagers, new java.security.SecureRandom());
javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
return sslSocketFactory;
}
catch (Exception ex)
{
return null;
}
}
}
URLにアクセスするためのコード:
SSLTrustManager sslTrustManager = new SSLTrustManager();
HttpsURLConnection.setDefaultSSLSocketFactory(sslTrustManager.GetSocketFactory());
URL siteUrl = new URL(url);
HttpsURLConnection conn = (HttpsURLConnection) siteUrl.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
DataOutputStream out = new DataOutputStream(conn.getOutputStream());