sirven - ssl android
SSL de Android-Sin certificado de pares (10)
A pesar de que esta pregunta tiene una respuesta aceptada, pensé que valía la pena responderla, ya que obtuve el mismo error en un dispositivo Android antiguo que ejecuta 2.3.3:
javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
Después de leer varias preguntas relacionadas diferentes sobre SO para llegar a la conclusión de que esto puede suceder por dos (¿quizás más?) Razones:
- Instalación inadecuada de un certificado intermedio
- Pedido incorrecto de la cadena de certificados
En mi caso fue un pedido incorrecto de certificados. Como ejemplo, estoy publicando el pedido de bdc de esta pregunta con la respuesta perspicaz del usuario bdc . Puede obtener el pedido de certificado haciendo lo siguiente desde un terminal:
openssl s_client -connect eu.battle.net:443
(obviamente reemplazando eu.battle.net con su propio servidor). En el caso de eu.battle.net en ese momento el pedido fue:
Certificate chain
0 s:/C=US/ST=California/L=Irvine/O=Blizzard Entertainment, Inc./CN=*.battle.net
i:/C=US/O=Thawte, Inc./CN=Thawte SSL CA
1 s:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
i:/C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting cc/OU=Certification Services Division/CN=Thawte Premium Server CA/[email protected]
2 s:/C=US/O=Thawte, Inc./CN=Thawte SSL CA
i:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
Mientras que debería haber sido:
Certificate chain
0 s:/C=US/ST=California/L=Irvine/O=Blizzard Entertainment, Inc./CN=*.battle.net
i:/C=US/O=Thawte, Inc./CN=Thawte SSL CA
1 s:/C=US/O=Thawte, Inc./CN=Thawte SSL CA
i:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
2 s:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
i:/C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting cc/OU=Certification Services Division/CN=Thawte Premium Server CA/[email protected]
La regla es que el emisor de cert "n" en la cadena debe coincidir con el sujeto de cert "n + 1".
Una vez que encontré el problema, era trivial cambiar el orden del certificado en el servidor y las cosas comenzaron a funcionar inmediatamente en el dispositivo Android 2.3.3. Supongo que es bueno que las versiones anteriores de Android sean un poco molestas con respecto al pedido de certificados, pero también fue una pesadilla ya que las nuevas versiones de Android reordenan los certificados automáticamente. Demonios, incluso un viejo iPhone 3GS funcionaba con certificados descompuestos.
Cada vez que se ejecuta este código, aparece el error "No Peer Certificate".
El certificado SSL es válido, comprado en Namecheap (PositiveSSL). Tiene el crt CA antes de él, y se abre bien en el navegador de Android.
Servidor HTTP: nginx
Código:
public void postData() {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("string", "myfirststring"));
try {
HttpPost post = new HttpPost(new URI("https://example.com/submit"));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
KeyStore trusted = KeyStore.getInstance("BKS");
trusted.load(null, "".toCharArray());
SSLSocketFactory sslf = new SSLSocketFactory(trusted);
sslf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme ("https", sslf, 443));
SingleClientConnManager cm = new SingleClientConnManager(post.getParams(),
schemeRegistry);
HttpClient client = new DefaultHttpClient(cm, post.getParams());
// Execute HTTP Post Request
@SuppressWarnings("unused")
HttpResponse result = client.execute(post);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
Log.e(TAG,e.getMessage());
Log.e(TAG,e.toString());
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e(TAG,e.getMessage());
Log.e(TAG,e.toString());
e.printStackTrace();
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
Log.e(TAG,e.getMessage());
Log.e(TAG,e.toString());
e.printStackTrace();
} catch (KeyStoreException e) {
// TODO Auto-generated catch block
Log.e(TAG,e.getMessage());
Log.e(TAG,e.toString());
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
Log.e(TAG,e.getMessage());
Log.e(TAG,e.toString());
e.printStackTrace();
} catch (CertificateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e(TAG,e.toString());
Log.e(TAG,e.getMessage());
} catch (KeyManagementException e) {
// TODO Auto-generated catch block
Log.e(TAG,e.getMessage());
Log.e(TAG,e.toString());
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
// TODO Auto-generated catch block
Log.e(TAG,e.getMessage());
Log.e(TAG,e.toString());
e.printStackTrace();
}
}
Adb Logcat :
01-10 15:44:34.872: E/myfirstapp(572): No peer certificate
01-10 15:44:34.872: E/myfirstapp(572): javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
01-10 15:44:34.883: W/System.err(572): javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
01-10 15:44:34.883: W/System.err(572): at org.apache.harmony.xnet.provider.jsse.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:137)
01-10 15:44:34.883: W/System.err(572): at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:93)
01-10 15:44:34.908: W/System.err(572): at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:381)
01-10 15:44:34.908: W/System.err(572): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:165)
01-10 15:44:34.908: W/System.err(572): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
01-10 15:44:34.914: W/System.err(572): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
01-10 15:44:34.914: W/System.err(572): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
01-10 15:44:34.914: W/System.err(572): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
01-10 15:44:34.914: W/System.err(572): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
01-10 15:44:34.914: W/System.err(572): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
01-10 15:44:34.933: W/System.err(572): at com.giggsey.myfirstapp.myfirstappIntent.postData(myfirstappIntent.java:126)
01-10 15:44:34.933: W/System.err(572): at com.giggsey.myfirstapp.myfirstappIntent.onReceive(myfirstappIntent.java:77)
01-10 15:44:34.933: W/System.err(572): at android.app.ActivityThread.handleReceiver(ActivityThread.java:2118)
01-10 15:44:34.945: W/System.err(572): at android.app.ActivityThread.access$1500(ActivityThread.java:122)
01-10 15:44:34.945: W/System.err(572): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
01-10 15:44:34.952: W/System.err(572): at android.os.Handler.dispatchMessage(Handler.java:99)
01-10 15:44:34.952: W/System.err(572): at android.os.Looper.loop(Looper.java:137)
01-10 15:44:34.962: W/System.err(572): at android.app.ActivityThread.main(ActivityThread.java:4340)
01-10 15:44:34.962: W/System.err(572): at java.lang.reflect.Method.invokeNative(Native Method)
01-10 15:44:34.962: W/System.err(572): at java.lang.reflect.Method.invoke(Method.java:511)
01-10 15:44:34.972: W/System.err(572): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
01-10 15:44:34.972: W/System.err(572): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
01-10 15:44:34.981: W/System.err(572): at dalvik.system.NativeStart.main(Native Method)
Asegúrese de que está utilizando HttpsURLConnection
lugar de HttpURLConnection
.
Como el certificado es válido, no debe usar SchemeRegistry personalizado, solo debe confiar en el mecanismo de validación de certificados de Android predeterminado.
Eliminé todo el personal del Registro de Esquemas y se solucionó el error "No Certification Peer".
es decir.
Quito este código del mío
SchemeRegistry schReg = new SchemeRegistry();
schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schReg.register(new Scheme("https",SSLSocketFactory.getSocketFactory(), 443));
SingleClientConnManager conMgr = new SingleClientConnManager(params,post.getParams());
Puede ser que puedas intentar quitarlos de los tuyos.
En realidad, estoy intentando diagnosticar esto ahora mismo, y parece que una cosa que puede causar este problema es que el servidor está inactivo o que la conexión se agota.
Este documento puede resumir todo lo que necesita saber para que su SSL funcione en Android. Según mi experiencia reciente, el mejor enfoque es obtener un certificado SSL que le guste a Android.
Intenté arreglar esto desde el código de Android agregando una regla de "aceptar todos los certificados". Pero todo el esfuerzo desde el lado de Android fue inútil. Finalmente, haciendo un CNAME en la entrada del registrador que aseguró que todas las solicitudes fueran a la misma dirección IP solucionó el problema
Recientemente he pasado por este problema. No fue el orden de la cadena el problema, pero lo he tenido antes.
El problema fue que el servidor solo acepta conexiones de socket TLS1.2. Android 19 y la conexión de zócalo predeterminada más baja es TLS1 SSLSocket Docs
Con la ayuda de Habilitar TLS 1.2 en Android 4.4 , pude hacer que esto funcionara. La descripción de la pregunta funcionó para mí. Pero asegúrese de tener el código de respuesta en su solicitud
Si no es un problema del servidor, que en la mayoría de los casos que he visto este problema está relacionado con la falta de certificados intermedios o la mala instalación de los mismos.
Intenta usar el Registro de Esquemas de esta manera:
SchemeRegistry schReg = new SchemeRegistry();
schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schReg.register(new Scheme("https",SSLSocketFactory.getSocketFactory(), 443));
SingleClientConnManager conMgr = new SingleClientConnManager(params,post.getParams());
Verifique la hora del sistema. Si la hora no es la hora actual, se puede producir este error.