
Crispix
Estoy tratando de conectarme a un cuadro IIS6 que ejecuta un certificado SSL de 256 bits de Godaddy, y recibo el error:
java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
He estado tratando de determinar qué podría estar causando eso, pero ahora mismo estoy en blanco.
Así es como me estoy conectando:
HttpsURLConnection conn;
conn = (HttpsURLConnection) (new URL(mURL)).openConnection();
conn.setConnectTimeout(20000);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.connect();
String tempString = toString(conn.getInputStream());
Contrariamente a la respuesta aceptada que no necesita un administrador de confianza personalizado, ¡necesita arreglar la configuración de su servidor!
Me encontré con el mismo problema al conectarme a un servidor Apache con un certificado dynadot/alphassl instalado incorrectamente. Me estoy conectando usando HttpsUrlConnection (Java/Android), que lanzaba:
javax.net.ssl.SSLHandshakeException:
java.security.cert.CertPathValidatorException:
Trust anchor for certification path not found.
El problema real es una configuración incorrecta del servidor: pruébelo con http://www.digicert.com/help/ o similar, e incluso te dirá la solución:
“El certificado no está firmado por una autoridad de confianza (comprobando con el almacén raíz de Mozilla). Si compró el certificado de una autoridad de confianza, probablemente solo necesite instalar uno o más certificados intermedios. Comuníquese con su proveedor de certificados para obtener ayuda para hacer esto para su plataforma de servidor”.
También puede verificar el certificado con openssl:
openssl s_client -debug -connect www.thedomaintocheck.com:443
Probablemente verás:
Verify return code: 21 (unable to verify the first certificate)
y, anteriormente en la salida:
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=27:certificate not trusted
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=21:unable to verify the first certificate`
La cadena de certificados solo contendrá 1 elemento (su certificado):
Certificate chain
0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
i:/O=AlphaSSL/CN=AlphaSSL CA - G2
… pero debe hacer referencia a las autoridades de firma en una cadena de regreso a una en la que Android confíe (Verisign, GlobalSign, etc.):
Certificate chain
0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
i:/O=AlphaSSL/CN=AlphaSSL CA - G2
1 s:/O=AlphaSSL/CN=AlphaSSL CA - G2
i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
2 s:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
Las instrucciones (y los certificados intermedios) para configurar su servidor generalmente las proporciona la autoridad que emitió su certificado, por ejemplo: http://www.alphassl.com/support/install-root-certificate.html
Después de instalar los certificados intermedios proporcionados por el emisor de mi certificado, ahora no tengo errores al conectarme mediante HttpsUrlConnection.

Matías B.
¡La solución de @Chrispix es peligrosa! Confiar en todos los certificados le permite a cualquiera hacer un ataque de hombre en el medio. ¡Simplemente envíe CUALQUIER certificado al cliente y lo aceptará!
Agregue su(s) certificado(s) a un administrador de confianza personalizado como se describe en esta publicación: Confiar en todos los certificados usando HttpClient sobre HTTPS
Aunque es un poco más complejo establecer una conexión segura con un certificado personalizado, le brindará la seguridad de cifrado SSL deseada sin el peligro de un ataque de hombre en el medio.
Puede confiar en un certificado particular en tiempo de ejecución.
Simplemente descárguelo del servidor, coloque activos y cárguelo así usando ssl-utils-android:
OkHttpClient client = new OkHttpClient();
SSLContext sslContext = SslUtils.getSslContextForCertificateFile(context, "BPClass2RootCA-sha2.cer");
client.setSslSocketFactory(sslContext.getSocketFactory());
En el ejemplo anterior usé OkHttpClient
pero SSLContext
se puede utilizar con cualquier cliente en Java.
Si usted tiene alguna pregunta no dude en preguntar. Soy el autor de esta pequeña biblioteca.

usuario1506104
Actualización basada en la última documentación de Android (marzo de 2017):
Cuando obtiene este tipo de error:
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:374)
at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209)
at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478)
at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:433)
at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282)
at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)
el problema podría ser uno de los siguientes:
- Se desconocía la CA que emitió el certificado del servidor
- El certificado del servidor no fue firmado por una CA, pero fue autofirmado
- A la configuración del servidor le falta una CA intermedia
La solución es enseñar. HttpsURLConnection
para confiar en un conjunto específico de CA. ¿Cómo? por favor, compruebe https://developer.android.com/training/articles/security-ssl.html#CommonProblems
Otros que están usando AsyncHTTPClient
desde com.loopj.android:android-async-http
biblioteca, verifique Configurar AsyncHttpClient para usar HTTPS.

Shihab Udin
Si usa la actualización, necesita personalizar su OkHttpClient
.
retrofit = new Retrofit.Builder()
.baseUrl(ApplicationData.FINAL_URL)
.client(getUnsafeOkHttpClient().build())
.addConverterFactory(GsonConverterFactory.create())
.build();
El código completo es el siguiente.
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;
}
}

usuario28434’mstep
Respondiendo a un mensaje muy antiguo. Pero tal vez ayude a algunos novatos y si nada de lo anterior funciona.
Explicación: Sé que nadie quiere una mierda de explicación; más bien la solución. Pero en una línea, está intentando acceder a un servicio desde su máquina local a una máquina remota que no confía en su máquina. Su solicitud necesita ganarse la confianza del servidor remoto.
Solución: La siguiente solución asume que se cumplen las siguientes condiciones
- Intentando acceder a una API remota desde su máquina local.
- Estás construyendo para la aplicación de Android
- Su servidor remoto está bajo filtración de proxy (usted usa proxy en la configuración de su navegador para acceder al servicio de API remoto, generalmente un servidor de prueba o de desarrollo)
- Estás probando en un dispositivo real
Pasos:
Necesita un archivo de extensión .keystore para registrar su aplicación. Si no sabe cómo crear un archivo .keystore; luego sigue junto con lo siguiente sección Crear archivo .keystore o salte a la siguiente sección Firmar archivo apk
Crear archivo .keystore
Abra Android Studio. Haz clic en el menú superior Generar > Generar APK firmado. En la siguiente ventana, haga clic en el Crear nuevo… botón. En la nueva ventana, ingrese los datos en todos los campos. Recuerde que los dos campos de Contraseña que recomiendo deben tener la misma contraseña; no use una contraseña diferente; y también recuerde la ruta de guardado en la parte superior del campo Ruta del almacén de claves:. Después de ingresar todo el campo, haga clic en el botón Aceptar.
Firmar archivo apk
Ahora necesita crear una aplicación firmada con el archivo .keystore que acaba de crear. Sigue estos pasos
- Build > Clean Project, espere hasta que termine de limpiar
- Generar > Generar APK firmado
- Hacer clic
Choose existing...
botón
- Seleccione el archivo .keystore que acabamos de crear en el Crear archivo .keystore sección
- Ingrese la misma contraseña que creó al crear en Crear archivo .keystore sección. Usar la misma contraseña para
Key store password
y Key password
campos. Introduzca también el alias
- Haga clic en el botón Siguiente
- En la siguiente pantalla; que podría ser diferente en función de su configuración en
build.gradle
archivos, debe seleccionar Build Types
y Flavors
.
- Para el
Build Types
escoger release
del menú desplegable
-
Para Flavors
sin embargo, dependerá de su configuración en build.gradle
expediente. Escoger staging
de este campo. Utilicé la siguiente configuración en el build.gradle
puedes usar el mismo que el mío, pero asegúrate de cambiar el applicationId
a su nombre de paquete
productFlavors {
staging {
applicationId "com.yourapplication.package"
manifestPlaceholders = [icon: "@drawable/ic_launcher"]
buildConfigField "boolean", "CATALYST_DEBUG", "true"
buildConfigField "boolean", "ALLOW_INVALID_CERTIFICATE", "true"
}
production {
buildConfigField "boolean", "CATALYST_DEBUG", "false"
buildConfigField "boolean", "ALLOW_INVALID_CERTIFICATE", "false"
}
}
-
Haga clic en los dos inferiores Signature Versions
casillas de verificación y haga clic en Finish
botón.
Casi llegamos:
Todo el trabajo duro está hecho, ahora el movimiento de la verdad. Para acceder al servidor de prueba respaldado por proxy, debe realizar alguna configuración en sus dispositivos Android de prueba reales.
Configuración de proxy en el dispositivo Android:
- Haga clic en Configuración dentro del teléfono Android y luego wi-fi
- Mantenga presionado el wifi conectado y seleccione
Modify network
- Haga clic en el
Advanced options
si no puedes ver el Proxy Hostname
campo
- En el
Proxy Hostname
ingrese la IP del host o el nombre que desea conectar. Un servidor de ensayo típico se denominará como stg.api.mygoodcompany.com
- Para el puerto, ingrese el número de puerto de cuatro dígitos, por ejemplo
9502
- Golpea el
Save
botón
Una última parada:
Recuerde que generamos el archivo apk firmado en Firmar archivo APK sección. Ahora es el momento de instalar ese archivo APK.
- Abra una terminal y cambie a la carpeta de archivos apk firmada
- Conecte su dispositivo Android a su máquina
- Elimine cualquier archivo apk instalado anteriormente del dispositivo Android
- Correr
adb install
name of the apk file
- Si por alguna razón el comando anterior regresa con
adb command not found
. Introduzca la ruta completa como C:\Users\shah\AppData\Local\Android\sdk\platform-tools\adb.exe
install
name of the apk file
Espero que se pueda solucionar el problema. Si no, déjame un comentario.
¡Salam!
Utilizar https://www.ssllabs.com/ssltest/ para probar un dominio.
La solución de Shihab Uddin en 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)
}
}
El mismo error también aparecerá si usa Glide
, las imágenes no se mostrarán. Para superarlo, consulte Glide – javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Anclaje de confianza para la ruta de certificación no encontrada y Cómo configurar OkHttpClient para 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))
}
}
construir.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'
ACTUALIZAR
También recibí otro error en el emulador API 16:
rutinas:SSL23_GET_SERVER_HELLO:versión del protocolo de alerta tlsv1 (external/openssl/ssl/s23_clnt.c:741′.
Leer 1 y 2, cambié el código así que:
okHttpClient = getOkHttpBuilder().build()
private fun getOkHttpBuilder(): OkHttpClient.Builder {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Security.insertProviderAt(Conscrypt.newProvider(), 1)
}
return OkHttpClient().newBuilder()
}
// build.gradle:
implementation 'org.conscrypt:conscrypt-android:2.5.1'
También eliminé estas líneas de MyApplication
:
try {
ProviderInstaller.installIfNeeded(applicationContext)
val sslContext = SSLContext.getInstance("TLSv1.2")
sslContext.init(null, null, null)
sslContext.createSSLEngine()
} catch (e: GooglePlayServicesRepairableException) {
Timber.e(e.stackTraceToString())
// Prompt the user to install/update/enable Google Play services.
GoogleApiAvailability.getInstance().showErrorNotification(this, e.connectionStatusCode)
} catch (e: GooglePlayServicesNotAvailableException) {
Timber.e(e.stackTraceToString())
// Prompt the user to install/update/enable Google Play services.
// GoogleApiAvailability.getInstance().showErrorNotification(this, e.errorCode)
} catch (e: NoSuchAlgorithmException) {
Timber.e(e.stackTraceToString())
} catch (e: KeyManagementException) {
Timber.e(e.stackTraceToString())
}
Pero el Biblioteca agrega 3.4 Mb a apk.