seguridad - para que sirven los certificados wifi en android
¿Cómo instalar un certificado de CA confiable en un dispositivo Android? (7)
Antes de Android KitKat, debe rootear su dispositivo para instalar nuevos certificados.
Desde Android KitKat (4.0) hasta Nougat (7.0) es posible y fácil. Pude instalar el certificado de proxy de depuración web de Charles en mi dispositivo no rooteado y olfatear con éxito el tráfico SSL.
Extracto de http://wiki.cacert.org/FAQ/ImportRootCert
Antes de Android versión 4.0, con la versión de Android Gingerbread & Froyo, había un único archivo de solo lectura (/system/etc/security/cacerts.bks) que contenía el almacén de confianza con todos los certificados de CA (''sistema'') confiables por defecto en Androide. Tanto las aplicaciones del sistema como todas las aplicaciones desarrolladas con Android SDK usan esto. Siga estas instrucciones para instalar certificados CAcert en Android Gingerbread, Froyo, ...
A partir de Android 4.0 (Android ICS / ''Ice Cream Sandwich'', Android 4.3 ''Jelly Bean'' y Android 4.4 ''KitKat''), los certificados de confianza del sistema se encuentran en la partición del sistema (solo lectura) en la carpeta ''/ system / etc / seguridad / ''como archivos individuales. Sin embargo, los usuarios ahora pueden agregar fácilmente sus propios certificados de ''usuario'' que se almacenarán en ''/ data / misc / keychain / certs-added''.
Los certificados instalados en el sistema se pueden administrar en el dispositivo Android en la sección Configuración -> Seguridad -> Certificados -> ''Sistema'', mientras que los certificados de confianza del usuario se gestionan en la sección ''Usuario'' allí. Al usar certificados de confianza del usuario, Android forzará al usuario del dispositivo Android a implementar medidas de seguridad adicionales: el uso de un código PIN, un patrón de bloqueo o una contraseña para desbloquear el dispositivo son obligatorios cuando se usan certificados proporcionados por el usuario.
La instalación de certificados CAcert como certificados ''user trusted'' es muy fácil. La instalación de certificados nuevos como certificados ''de confianza del sistema'' requiere más trabajo (y requiere acceso raíz), pero tiene la ventaja de evitar el requisito de bloqueo de pantalla de Android.
Desde Android N en adelante se vuelve un poco más difícil, vea este extracto del sitio web proxy de Charles :
A partir de Android N, debe agregar la configuración a su aplicación para que confíe en los certificados SSL generados por Charles SSL Proxying. Esto significa que solo puede usar SSL Proxying con las aplicaciones que controla.
Para configurar su aplicación para que confíe en Charles, debe agregar un archivo de configuración de seguridad de red a su aplicación. Este archivo puede anular el valor predeterminado del sistema, lo que permite que su aplicación confíe en los certificados de CA instalados por el usuario (por ejemplo, el certificado de Charles Root). Puede especificar que esto solo se aplica a las versiones de depuración de su aplicación, de modo que las compilaciones de producción utilicen el perfil de confianza predeterminado.
Agregue un archivo res / xml / network_security_config.xml a su aplicación:
<network-security-config>
<debug-overrides>
<trust-anchors>
<!-- Trust user added CAs while debuggable only -->
<certificates src="user" />
</trust-anchors>
</debug-overrides>
</network-security-config>
A continuación, agregue una referencia a este archivo en el manifiesto de su aplicación, de la siguiente manera:
<?xml version="1.0" encoding="utf-8"?>
<manifest>
<application android:networkSecurityConfig="@xml/network_security_config">
</application>
</manifest>
He creado mi propio certificado de CA y ahora quiero instalarlo en mi dispositivo Android Froyo (HTC Desire Z), para que el dispositivo confíe en mi certificado.
Android almacena certificados CA en su almacén de claves Java en /system/etc/security/cacerts.bks
. Copié el archivo a mi computadora, agregué mi certificado usando portecle 1.5 y lo devolví al dispositivo.
Ahora, Android no parece volver a cargar el archivo automáticamente. He leído en varias publicaciones de blog que necesito para reiniciar el dispositivo. Si lo hace, el archivo se sobrescribirá con el original nuevamente.
Mi siguiente intento fue instalar el certificado de la tarjeta SD copiándolo y usando la opción correspondiente en el menú de configuración. El dispositivo me dice que el certificado ha sido instalado, pero aparentemente no confía en el certificado. Además, cuando intento copiar el almacén de claves a mi computadora, todavía encuentro el stock original cacerts.bks
.
Entonces, ¿cuál es la forma correcta de instalar mi propio certificado raíz de CA en un dispositivo con Android 2.2 como certificado de confianza? ¿Hay alguna manera de hacerlo programáticamente?
Aquí hay una solución alternativa que realmente agrega su certificado a la lista incorporada de certificados predeterminados: Confiar en todos los certificados que usan HttpClient a través de HTTPS
Sin embargo, solo funcionará para su aplicación. No hay forma de hacerlo programáticamente para todas las aplicaciones en el dispositivo de un usuario, ya que eso sería un riesgo para la seguridad.
Hay una solución MUCHO más fácil para esto que publicada aquí, o en hilos relacionados. Si está utilizando una vista web (como yo), puede lograr esto ejecutando una función JAVASCRIPT dentro de ella. Si no está utilizando una vista web, es posible que desee crear una oculta para este fin. Aquí hay una función que funciona en casi cualquier navegador (o vista web) para la instalación de kickoff ca (generalmente a través del depósito de certificados de os comunes, incluso en un Droid). Utiliza un buen truco con iFrames. Simplemente pase la url a un archivo .crt a esta función:
function installTrustedRootCert( rootCertUrl ){
id = "rootCertInstaller";
iframe = document.getElementById( id );
if( iframe != null ) document.body.removeChild( iframe );
iframe = document.createElement( "iframe" );
iframe.id = id;
iframe.style.display = "none";
document.body.appendChild( iframe );
iframe.src = rootCertUrl;
}
ACTUALIZAR:
El truco iframe funciona en Droids con API 19 en adelante, pero las versiones anteriores de la vista web no funcionan así. La idea general aún funciona: simplemente descargue / abra el archivo con una vista web y luego deje que el sistema operativo se haga cargo. Esta puede ser una solución más fácil y más universal (en el java actual):
public static void installTrustedRootCert( final String certAddress ){
WebView certWebView = new WebView( instance_ );
certWebView.loadUrl( certAddress );
}
Tenga en cuenta que instance_ es una referencia a la actividad. Esto funciona perfectamente si conoce la URL del certificado. En mi caso, sin embargo, lo resuelvo dinámicamente con el software del lado del servidor. Tuve que agregar una buena cantidad de código adicional para interceptar una url de redirección y llamar a esto de una manera que no causara un bloqueo basado en una complicación de subprocesamiento, pero no añadiré toda esa confusión aquí ...
La guía vinculada here probablemente responda la pregunta original sin la necesidad de programar un conector SSL personalizado.
Encontré una guía práctica muy detallada sobre la importación de certificados raíz que realmente lo guían a través de la instalación de certificados de CA confiables en diferentes versiones de dispositivos Android (entre otros dispositivos).
Básicamente, necesitarás:
Descargar: el archivo cacerts.bks de su teléfono.
adb pull /system/etc/security/cacerts.bks cacerts.bks
Descargue el archivo .crt de la autoridad de certificación que desea permitir.
Modifique el archivo cacerts.bks en su computadora con el proveedor BouncyCastle
Suba el archivo cacerts.bks a su teléfono y reinicie.
Aquí hay un paso por paso más detallado para actualizar teléfonos Android anteriores: Cómo actualizar la autoridad de certificación de seguridad HTTPS keystore en el dispositivo pre-android-4.0
Lo que hice para poder usar los certificados de startssl fue bastante fácil. (en mi teléfono rooteado)
Copié /system/etc/security/cacerts.bks a mi tarjeta sd
Descargado http://www.startssl.com/certs/ca.crt y http://www.startssl.com/certs/sub.class1.server.ca.crt
Fue a portecle.sourceforge.net y ejecutó portecle directamente desde la página web.
Abrí mi archivo cacerts.bks desde mi tarjeta SD (ingresé nada cuando me pidieron una contraseña)
Elija importar en portacle y abra sub.class1.server.ca.crt, en mi caso ya tenía el ca.crt pero tal vez también deba instalarlo.
Guarde el almacén de claves y lo copió en baxck a /system/etc/security/cacerts.bks (primero hice una copia de seguridad de ese archivo por si acaso)
Reinicié mi teléfono y ahora puedo visitar mi sitio usando un certificado startssl sin errores.
Pasé mucho tiempo tratando de encontrar una respuesta a esto (necesito Android para ver los certificados de StartSSL). Conclusión: Android 2.1 y 2.2 le permiten importar certificados, pero solo para usar con WiFi y VPN. No hay una interfaz de usuario para actualizar la lista de certificados raíz de confianza, pero hay un debate sobre cómo agregar esa función. No está claro si existe una solución confiable para actualizar y reemplazar manualmente el archivo cacerts.bks.
Detalles y enlaces: http://www.mcbsys.com/techblog/2010/12/android-certificates/ . En esa publicación, vea el enlace al error 11231 de Android: es posible que desee agregar su voto y consulta a ese error.
Si necesita su certificado para conexiones HTTPS, puede agregar el archivo .bks como recurso sin formato a su aplicación y extender DefaultHttpConnection para que sus certificados se utilicen para conexiones HTTPS.
public class MyHttpClient extends DefaultHttpClient {
private Resources _resources;
public MyHttpClient(Resources resources) {
_resources = resources;
}
@Override
protected ClientConnectionManager createClientConnectionManager() {
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
if (_resources != null) {
registry.register(new Scheme("https", newSslSocketFactory(), 443));
} else {
registry.register(new Scheme("https", SSLSocketFactory
.getSocketFactory(), 443));
}
return new SingleClientConnManager(getParams(), registry);
}
private SSLSocketFactory newSslSocketFactory() {
try {
KeyStore trusted = KeyStore.getInstance("BKS");
InputStream in = _resources.openRawResource(R.raw.mystore);
try {
trusted.load(in, "pwd".toCharArray());
} finally {
in.close();
}
return new SSLSocketFactory(trusted);
} catch (Exception e) {
throw new AssertionError(e);
}
}
}