I am trying to connect to an IIS6 box running a godaddy 256bit SSL cert, and I am getting the error :
java.security.cert.CertPathValidatorException: Trust an
I had the same problem what i found was that the certificate .crt file i provided missing an intermediate certificate. So I asked all .crt files from my server admin, then concatinated them in reverse order.
Ex. 1. Root.crt 2. Inter.crt 3. myCrt.crt
in windows i executed copy Inter.crt + Root.crt newCertificate.crt
(Here i ignored myCrt.crt)
Then i provided newCertificate.crt file into code via inputstream. Work done.
Use https://www.ssllabs.com/ssltest/ to test a domain.
The solution of Shihab Uddin in Kotlin.
import java.security.SecureRandom
import java.security.cert.X509Certificate
import javax.net.ssl.*
import javax.security.cert.CertificateException
object {
val okHttpClient: OkHttpClient
val gson: Gson
val retrofit: Retrofit
init {
okHttpClient = getOkHttpBuilder()
// Other parameters like connectTimeout(15, TimeUnit.SECONDS)
.build()
gson = GsonBuilder().setLenient().create()
retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
}
fun getOkHttpBuilder(): OkHttpClient.Builder =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
OkHttpClient().newBuilder()
} else {
// Workaround for the error "Caused by: com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate: Certificate expired at".
getUnsafeOkHttpClient()
}
private fun getUnsafeOkHttpClient(): OkHttpClient.Builder =
try {
// Create a trust manager that does not validate certificate chains
val trustAllCerts: Array<TrustManager> = arrayOf(
object : X509TrustManager {
@Throws(CertificateException::class)
override fun checkClientTrusted(chain: Array<X509Certificate?>?,
authType: String?) = Unit
@Throws(CertificateException::class)
override fun checkServerTrusted(chain: Array<X509Certificate?>?,
authType: String?) = Unit
override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
}
)
// Install the all-trusting trust manager
val sslContext: SSLContext = SSLContext.getInstance("SSL")
sslContext.init(null, trustAllCerts, SecureRandom())
// Create an ssl socket factory with our all-trusting manager
val sslSocketFactory: SSLSocketFactory = sslContext.socketFactory
val builder = OkHttpClient.Builder()
builder.sslSocketFactory(sslSocketFactory,
trustAllCerts[0] as X509TrustManager)
builder.hostnameVerifier { _, _ -> true }
builder
} catch (e: Exception) {
throw RuntimeException(e)
}
}
The same error will also appear if you use Glide
, images won't show. To overcome it see Glide - javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found and How to set OkHttpClient for glide.
@GlideModule
class MyAppGlideModule : AppGlideModule() {
val okHttpClient = Api.getOkHttpBuilder().build() // Api is the class written above.
// It is better to create okHttpClient here and not use Api.okHttpClient,
// because their settings may differ. For instance, it can use its own
// `addInterceptor` and `addNetworkInterceptor` that can affect on a read JSON.
override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
registry.replace(GlideUrl::class.java, InputStream::class.java,
OkHttpUrlLoader.Factory(okHttpClient))
}
}
build.gradle:
// Glide.
implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation 'com.github.bumptech.glide:okhttp3-integration:4.11.0'
kapt 'com.github.bumptech.glide:compiler:4.11.0'
**Set proper alias name**
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509","BC");
X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(derInputStream);
String alias = cert.getSubjectX500Principal().getName();
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null);
trustStore.setCertificateEntry(alias, cert);
I know this is a very old article, but I came across this article when trying to solve my trust anchor issues. I have posted how I fixed it. If you have pre-installed your Root CA you need to add a configuration to the manifest.
https://stackoverflow.com/a/60102517/114265
If you use retrofit, you need to customize your OkHttpClient.
retrofit = new Retrofit.Builder() .baseUrl(ApplicationData.FINAL_URL) .client(getUnsafeOkHttpClient().build()) .addConverterFactory(GsonConverterFactory.create()) .build();
Full code are as below.
public class RestAdapter {
private static Retrofit retrofit = null;
private static ApiInterface apiInterface;
public static OkHttpClient.Builder getUnsafeOkHttpClient() {
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
return builder;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static ApiInterface getApiClient() {
if (apiInterface == null) {
try {
retrofit = new Retrofit.Builder()
.baseUrl(ApplicationData.FINAL_URL)
.client(getUnsafeOkHttpClient().build())
.addConverterFactory(GsonConverterFactory.create())
.build();
} catch (Exception e) {
e.printStackTrace();
}
apiInterface = retrofit.create(ApiInterface.class);
}
return apiInterface;
}
}