Solución:
Estoy respondiendo a esto para dar una idea sobre el escenario y la solución según el sitio de desarrolladores de Android para que otros se beneficien. He resuelto esto usando un administrador de confianza personalizado.
El problema fue con el certificado del servidor, falta la autoridad de certificación intermedia. Sin embargo, con el primer flujo, la ruta del certificado se completa de alguna manera y el resultado fue una validación exitosa de la ruta del certificado.
Hay una solución para esto en el sitio de desarrolladores de Android. sugiere usar un administrador de confianza personalizado que confíe en este certificado de servidor o sugiere al servidor que incluya la CA intermedia en la cadena del servidor.
administrador de confianza personalizado. fuente: https://developer.android.com/training/articles/security-ssl.html#UnknownCa
// Load CAs from an InputStream
// (could be from a resource or ByteArrayInputStream or ...)
CertificateFactory cf = CertificateFactory.getInstance("X.509");
// From https://www.washington.edu/itconnect/security/ca/load-der.crt
InputStream caInput = new BufferedInputStream(new FileInputStream("load-der.crt"));
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
// Tell the okhttp to use a SocketFactory from our SSLContext
OkHttpClient okHttpClient client = new OkHttpClient.Builder().sslSocketFactory(context.getSocketFactory()).build();
ACTUALIZAR: Mi problema se resolvió después de que se agregó una autoridad de certificación intermedia a la cadena de certificados desde el lado del servidor. Es la mejor solución. Empaquetar el certificado con la aplicación requiere que la aplicación se actualice cuando el certificado expire o cualquier otro problema relacionado con la administración de certificados.
ACTUALIZACIÓN: 03/09/2017 La forma más fácil de cargar el archivo de certificado que encontré es el uso de recursos en bruto.
InputStream caInput = new BufferedInputStream(context
.getResources().openRawResource(R.raw.certfilename));
donde certfilename es el archivo de certificado ubicado en la carpeta resources / raw. También okhttp’s sslSocketFactory(SSLSocketFactory sslSocketFactory)
se ha desaprobado y se puede utilizar el enfoque sugerido en el documento okhttp api.
Además, al obtener el certificado del servidor, es mejor usar openssl.
openssl s_client -connect {server-address}:{port} -showcerts
Porque solía tomar eso de Firefox y enfrenté una situación en la que fue alterado por el protector de virus.