﻿<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="static/feed.xsl"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>CelerSMS</title>
<language>es</language>
<copyright>Copyright CelerSMS, 2019-2026, Todos los derechos reservados.</copyright>
<webMaster>admin@celersms.com (Miguel Angel Cano)</webMaster>
<pubDate>Mon, 26 Dec 2022 09:32:00 GMT</pubDate>
<link>https://www.celersms.com/index-es.htm</link>
<description>Artículos técnicos acerca de IoT, M2M y tecnologías de comunicación, geolocalización y desarrollo de aplicaciones</description>
<atom:link href="https://www.celersms.com/feed-es.xml" rel="self" type="application/rss+xml"/>
<image>
	<title>CelerSMS</title>
	<url>https://www.celersms.com/static/celer.png</url>
	<link>https://www.celersms.com/index-es.htm</link>
</image>
<item>
	<title>Solución de Respuesta Automática por SMS Utilizando Software Gratuito</title>
	<pubDate>Mon, 26 Dec 2022 09:32:00 GMT</pubDate><author>admin@celersms.com (Victor Celer)</author>
	<link>https://www.celersms.com/sms-reply-back-kannel-es.htm</link><guid isPermaLink="true">https://www.celersms.com/sms-reply-back-kannel-es.htm</guid><description><![CDATA[
<p>Las soluciones de respuesta automática por SMS se usan para asignación de turnos y emisión de comprobantes, votación electrónica, encuestas, suscripción y cancelación de servicios, entre muchos otros casos de uso. El usuario envía un SMS con una palabra clave y recibe una respuesta automática. En este artículo se explica cómo implementar este tipo de solución utilizando solamente software gratuito: el <a href="https://www.kannel.org/" target="_blank">Gateway de código abierto <b>Kannel</b></a> y la app gratuita <a href="smsproxy-es.htm"><b>SMS Proxy</b></a> para Android.
<p><center><img src="https://www.celersms.com/images/SMS-reply-back.png" alt="Una solución de respuesta automática por SMS utilizando Kannel y la app SMS Proxy"></center>
<p>&nbsp;
<h4>Centro de Mensajes (SMSC)</h4>
<p>El <b>Centro de Mensajes</b>, más oficialmente conocido como Central de Servicio de Mensajes Cortos (en inglés, <i>Short Message Service Center</i>) o SMSC, es el elemento de la red móvil que se encarga de enrutar, almacenar y despachar los mensajes SMS.<sup>1</sup> Generalmente, también puede gestionar la tasación, el filtrado (por ejemplo, la protección contra spam) y otras tareas relacionadas con la gestión de SMS. De todos modos, el objetivo principal del SMSC es almacenar y entregar los mensajes SMS. Los mensajes son almacenados hasta que el destinatario esté disponible para recibirlos o dichos mensajes expiren, lo que suceda primero. La función del SMSC es muy similar a la de un servidor de correo electrónico. Los e-mail no se intercambian punto a punto, sino que se entregan a través de un servidor de correo, el cual aplica un modelo de almacenamiento y reenvío (en inglés, <i>store-and-forward</i>). El SMSC es como un servidor de correo electrónico para SMS. El operador móvil puede tener múltiples SMSC. Cuando se envía un SMS a otro usuario, el SMS llegará primero al SMSC. Después de eso, el SMSC intentará entregarlo al usuario final.
<p>Hay casos especiales en los que el SMSC no funciona en modo <i>store-and-forward</i> o los SMS se entregan directamente al usuario final sin pasar por el SMSC. Estos casos especiales están por fuera del alcance de este artículo.
<p>Dado que el SMSC forma parte de la red móvil, la comunicación entre el teléfono y el SMSC es inalámbrica. Sin embargo, los proveedores de servicios prefieren tener una conexión de SMSC dedicada, lo cual puede ser más eficiente y especialmente útil para manejar grandes volúmenes de tráfico.
El operador móvil puede permitirles acceder al SMSC a través de una interfaz dedicada utilizando el <a href="https://es.wikipedia.org/wiki/SMPP" target="_blank">protocolo <b>SMPP</b></a>. Existen varios protocolos alternativos: CIMD2, UCP, SEMA e incluso algunas API basadas en HTTP, pero SMPP es el estándar <i>de facto</i> desde los años 90.
Actualmente hay más de 30 proveedores de SMSC y prácticamente todos ellos soportan SMPP. También existen proveedores de SMS masivos y concentradores de SMS, los cuales suelen exponer una API o interfaz dedicada para enviar y recibir SMS de la misma forma que un SMSC.
<p>&nbsp;
<h4>Gateway de SMS</h4>
<p>Estrictamente hablando, no es obligatorio utilizar un Gateway SMS para enviar y recibir SMS. Generalmente es posible interactuar con el SMSC directamente. El protocolo SMPP es un estándar abierto.<sup>2</sup> Cualquiera puede desarrollar un cliente SMPP o reutilizar una librería de código abierto, como <a href="https://github.com/OpenSmpp/opensmpp" target="_blank">OpenSmpp</a>, para interactuar con el SMSC sin intermediarios ni proxies. Sin embargo, el uso de un Gateway de SMS puede ser conveniente para evitar el desarrollo de una implementación propia. Típicamente el Gateway de SMS puede soportar diferentes protocolos de SMSC, no solo SMPP. También puede soportar el filtrado de SMS, la compartición de conexiones SMSC, enrutamiento, encolamiento, registro de logs, autenticación de usuarios, etc. El Gateway de código abierto Kannel tiene todas estas características y muchas más.
<p>Por supuesto, puede utilizar cualquier otro Gateway de SMS de su preferencia. Existen diferentes alternativas gratuitas. Por ejemplo, <a href="https://camel.apache.org/" target="_blank">Apache Camel</a> incluye un Gateway SMS integrado. <a href="https://github.com/jookies/jasmin" target="_blank">Jasmin</a> es otro Gateway de SMS de código abierto. También existen muchos Gateway de SMS comerciales. No obstante, en términos de estabilidad y rendimiento, Kannel funciona perfectamente para casi cualquier tipo de proyecto de SMS. Algunos operadores móviles utilizan Kannel incluso para servicios críticos para el negocio.
<p>&nbsp;
<h4>Proxy de SMSC</h4>
<p>Un proxy de SMSC es cualquier tipo de servicio intermediario entre el cliente SMS y el SMSC. Por ejemplo, el Gateway de SMS también puede actuar como un proxy de SMSC. Puede haber múltiples proxies, uno detrás de otro. Esto se conoce como una cadena de proxies. Por lo general, un proxy de SMSC se comporta como un proxy transparente. Esto significa que el proxy actúa como un SMSC real y el cliente de SMS puede no estar al tanto de la presencia del proxy.
<p>Es común que los operadores móviles prefieran suministrar el acceso a un proxy de SMSC en lugar del SMSC real. Los proxies pueden proporcionar una capa de protección adicional, balanceo de carga, filtrado, control de acceso, etc.
<p>En este artículo, el proxy de SMSC es una app para Android. Al igual que cualquier tipo de equipo móvil, el smartphone suele tener capacidad de envío y recepción de SMS. Por lo tanto, es posible usar una app para convertir el teléfono en un proxy de SMSC. Generalmente la capacidad de un teléfono para enviar y recibir mensajes es bastante limitada. Usualmente, el dispositivo y el operador móvil limitan el ancho de banda a unos pocos SMS por minuto. Si se supera el límite, el operador puede bloquear la suscripción para que no envíe más SMS de forma temporal o permanente. Por eso, si necesita enviar miles de SMS diariamente, definitivamente necesitará usar una conexión de SMSC dedicada en lugar de un solo teléfono móvil. El proxy de SMSC descrito en este artículo sirve para ahorrar tiempo y costos en la fase de prototipo de servicios nuevos de SMS, realizar pruebas unitarias o crear soluciones de bajo tráfico. Aunque la app es gratuita, tenga en cuenta que el operador móvil puede cobrar por cada SMS. En algunos países, las tarifas de SMS pueden ser bastante altas. Se recomienda consultar las tarifas locales de SMS para evitar costos inesperados.
<p>&nbsp;
<h4>Configuración de la app «SMS Proxy»</h4>
<p>La app se puede descargar <a href="https://www.amazon.es/gp/product/B08ZXSLGNN/ref=mas_pm_sms_proxy_lite" target="_blank">desde Amazon</a>. La versión SMS Proxy Lite es gratuita para cualquier propósito, incluido el uso comercial. No tiene limitaciones, anuncios o avisos de prueba.
<p>Si el teléfono tiene Android 6.0 (<i>Marshmallow</i>) o más reciente, al iniciar la app por primera vez, se solicitará otorgar los permisos para enviar y ver SMS. Es necesario otorgar estos permisos para que la app pueda enviar y recibir SMS. Las versiones anteriores de Android no solicitan estos permisos de manera explícita.
<p>La pantalla principal presenta 2 parámetros de configuración:
<p>&#x2022; <b>Puerto</b> es el número de puerto TCP, en el cual el proxy aguardará la conexión SMPP entrante. Puede ser cualquier valor en el rango de 1024 a 65535. Según IANA,<sup>3</sup> el número de puerto registrado para SMPP es 2775. En esta app, el valor por defecto es 5011.
<p>&#x2022; <b>Limitar</b> el tráfico a una determinada cantidad de SMS por minuto. Este límite puede ser cualquier valor en el rango de 1 a 100. El valor por defecto es 10. De manera predeterminada, Android limita el tráfico saliente a un máximo de 30 SMS cada 30 minutos. Si necesita aumentar este límite, intente buscar en Google por <code>sms_outgoing_check_max_count</code>. Este límite es una característica de seguridad. Si lo aumenta, existe el riesgo de que el tráfico saliente exceda lo permitido por el operador móvil. En ese caso, la línea puede ser bloqueada. Recuerde que el operador puede cobrar por cada SMS. Por lo tanto, no intente aumentar los límites a menos que sea realmente necesario. Ni Android ni la app limitan el tráfico entrante de SMS.
<p>Si se modifica el puerto o el límite de SMS por minuto, los nuevos valores serán tenidos en cuenta la próxima vez que se inicie el SMSC. Pulse el botón <b>Iniciar</b> para desplegar el SMSC.
<p>En Android 6.0 (<i>Marshmallow</i>) o posterior, existe una función de ahorro de batería que restringe las conexiones de red después de unos minutos de inactividad, si el cargador está desconectado. La app desplegará un mensaje de advertencia acerca de esta función cuando el SMSC se inicie por primera vez. Para evitar que el SMSC se desconecte después de unos minutos, puede mantener el cargador conectado o deshabilitar la optimización de batería para la app <b>SMS Proxy</b>. Esto último se puede realizar presionando el botón <b>Ajustes</b> para desplegar el listado de apps y el estado de optimización de batería correspondiente. Inicialmente la lista desplegará solo las apps sin optimización de batería. Puede ajustar el filtro para listar todas las apps. Después de eso, podrá encontrar en el listado la app <b>SMS Proxy</b> y deshabilitar la optimización de batería para dicha app. De esta manera podrá evitar desconexiones inesperadas. La app SMS Proxy está diseñada para ahorrar batería, incluso cuando la optimización de batería de Android está desactivada.
<p>Si WiFi está activa, el proxy utilizará la dirección IP del adaptador WiFi. En la parte inferior de la pantalla podrá ver un mensaje indicando que el SMSC espera conexión en X.X.X.X:YYYY, donde X.X.X.X es la IP (normalmente 192.168.X.X) y YYYY es el número de puerto configurado más arriba.
<p>Si WiFi no está activa, la dirección IP no se mostrará. En este caso, es posible conectar el cliente SMS a través de USB, configurando <a href="https://developer.android.com/studio/command-line/adb#forwardports" target="_blank">ADB con redirección de puertos</a>, por ejemplo:
<pre>
adb forward tcp:5011 tcp:5011
</pre>
<p>Mientras el túnel ADB esté activo, se podrá conectar con el proxy en 127.0.0.1:5011, a menos que haya cambiado el número de puerto.
<p>Tome nota de la IP y el número de puerto. Estos valores se configurarán en el Gateway Kannel para establecer la conexión SMPP. Mantenga la app SMS Proxy ejecutándose en primer plano para evitar desconexiones.
<p>&nbsp;
<h4>Configuración del Gateway «Kannel»</h4>
<p>Kannel se utiliza principalmente en Linux. Los instaladores están disponibles para muchas distribuciones populares de Linux. Por lo general, instalar Kannel en Linux requiere un solo clic o unos pocos comandos de consola. También es posible hacerlo funcionar en Windows y otros sistemas operativos. Si tiene una buena razón para no usar Linux, aunque no se me ocurre alguna, existen varios tutoriales que explican cómo ejecutar Kannel con Cygwin para Windows. En este artículo no usaremos ninguna herramienta externa, pero en cualquier proyecto de SMS de la vida real es necesario implementar scripts y servicios web para personalizar y automatizar la operación de Kannel. Linux y otros sistemas operativos Unix tienen todas las herramientas necesarias para esto. Esta es una de las razones por las que la mayoría de los proyectos de gran escala que utilizan Kannel se implementan en Linux.
<p>Para los novatos y los usuarios que no disponen de mucho tiempo libre para instalar Linux, existen sitios que permiten descargar imágenes preconfiguradas de Linux para máquinas virtuales como VMware o VirtualBox. Varios sitios web ofrecen imágenes para máquinas virtuales listas para usar de forma gratuita, por ejemplo: <a href="https://www.osboxes.org/" target="_blank">OSboxes</a>. Cuando utilice una máquina virtual para ejecutar Linux, asegúrese de configurar los adaptadores de red en modo puente para permitir la conectividad entre Linux y el teléfono Android.
<p>Mi servidor de pruebas es CentOS 7 para x64. Por lo tanto, descargué este instalador de Kannel preparado por <b>Roman Dmitriev</b>: <a href="http://rpm.pbone.net/info_idpl_41290272_distro_centos_7_com_kannel-1.4.4-1cnt7.x86_64.rpm.html" target="_blank">kannel-1.4.4-1cnt7.x86_64.rpm</a>. El RPM descargado se puede instalar directamente, por ejemplo:
<pre style="background:#000;color:#fff">
wget 'ftp://***/kannel-NNN.rpm'
sudo rpm -ivh kannel-NNN.rpm
</pre>
<p><b>Nota:</b> En el ejemplo anterior, simplemente reemplace <code>***</code> y <code>NNN</code> por la URL y el nombre del instalador apropiados, según la distribución de Linux y la CPU.
<p>Antes de iniciar Kannel, editemos su archivo de configuración principal. La ubicación predeterminada es <i>/etc/kannel.conf</i>:
<pre>
<b>group</b> = core
<b>admin-interface</b> = 127.0.0.1
<b>admin-port</b> = 13000
<b>admin-password</b> = modificar
<b>smsbox-interface</b> = 127.0.0.1
<b>smsbox-port</b> = 13001
<b>sms-resend-retry</b> = 1
<b>access-log</b> = /var/log/kannel/access.log
<b>log-file</b> = /var/log/kannel/kannel.log
<b>log-level</b> = 1

<b>group</b> = smsbox
<b>bearerbox-host</b> = 127.0.0.1
<b>sendsms-interface</b> = 127.0.0.1
<b>sendsms-port</b> = 13013
<b>global-sender</b> = 123

<b>group</b> = sendsms-user
<b>username</b> = ""
<b>password</b> = ""
<b>default-smsc</b> = celersms

<span style="color:#616a6b"># Esta es la conexion con la app SMS Proxy
# 192.168.X.X es la IP del adaptador WiFi del smartphone</span>
<b>group</b> = smsc
<b>smsc-id</b> = celersms
<b>smsc</b> = smpp
<b>host</b> = 192.168.20.22
<b>port</b> = 5011
<b>transceiver-mode</b> = 1
<b>smsc-username</b> = ""
<b>smsc-password</b> = ""
<b>system-type</b> = ""
<b>log-file</b> = /var/log/kannel/smpp.log

<span style="color:#616a6b"># Captura palabras clave SI y NO (mayusculas o minusculas)</span>
<b>group</b> = sms-service
<b>keyword-regex</b> = ^(?i)(si|no)$
<b>catch-all</b> = 1
<b>text</b> = Mensaje recibido (%t)
<b>max-messages</b> = 1

<span style="color:#616a6b"># Descarta todos los demas SMS</span>
<b>group</b> = sms-service
<b>keyword</b> = default
<b>text</b> = N/A
<b>max-messages</b> = 0
</pre>
<p>En la sección <code>core</code> configuramos la interfaz de administración. Esto es obligatorio, incluso si no vamos a enviar ningún comando administrativo. Por razones de seguridad, se recomienda evitar desplegar los puertos de Kannel en las interfaces de red públicas, a menos que sea necesario. En este ejemplo, desplegamos todos los puertos en la interfaz local 127.0.0.1 para restringir el acceso remoto. Si necesita permitir el acceso remoto, asegúrese de habilitar SSL y configurar contraseñas seguras para minimizar los riesgos de seguridad.
<p>Nuestro Gateway Kannel abrirá los siguientes tres puertos:
<p>&#x2022; <b>127.0.0.1:13000</b> es la interfaz de administración obligatoria
<p>&#x2022; <b>127.0.0.1:13001</b> es el servicio de <i>SMS box</i>
<p>&#x2022; <b>127.0.0.1:13013</b> es el puerto de <code>sendsms</code> (sirve para enviar SMS)
<p>Si alguno de estos puertos ya está en uso, puede cambiarlo. Tome nota del puerto <code>sendsms</code>, ya que este puerto se utilizará para enviar los mensajes SMS de prueba.
<p>Nótese que tenemos configurados dos servicios de SMS. El primero usa una expresión regular para capturar todos los mensajes con las palabras clave “SI” y “NO” (sin distinción entre mayúsculas y minúsculas) y responde con la fecha y hora cuando se recibió el mensaje. Como tal, este es nuestro servicio de respuesta automática. El segundo servicio captura todos los demás SMS y los descarta. Es necesario configurar un servicio predeterminado para ignorar los SMS no deseados, ya que de lo contrario Kannel responderá con un mensaje de error.
<p>Todos los logs se escriben en /var/log/kannel:
<p>&#x2022; <b>kannel.log</b> es el log principal que escribe el Gateway Kannel. Este es el primer log a revisar si el Gateway no inicia correctamente.
<p>&#x2022; <b>access.log</b> registra la actividad de SMS. Si necesita obtener el listado de usuarios que enviaron cierta palabra clave durante un período de tiempo específico, el log de acceso contiene esta información.
<p>&#x2022; <b>smpp.log</b> contiene las trazas del protocolo SMPP. Si se produce un error de conexión hacia la app de SMS Proxy, este log puede revelar mayor detalle acerca del problema.
<p>&nbsp;
<h4>Enviar y recibir SMS</h4>
<p>Intentemos iniciar el Gateway. Esto se puede hacer por medio del comando <code>service</code>:
<pre style="background:#000;color:#fff">
sudo service kannel start
</pre>
<p>Revise el contenido de <i>kannel.log</i> para ver si existe algún error. Si el Gateway se inició correctamente, revise <i>smpp.log</i> para ver si la conexión con la app SMS Proxy se estableció correctamente. Esto también se puede ver en la interfaz de usuario de la app. Si la conexión no es exitosa, verifique que la app se esté ejecutando en primer plano, no esté bloqueada por políticas de ahorro de batería, la IP y el puerto estén configurados correctamente y la conectividad no esté bloqueada por un <i>firewall</i>.
<p>Si todo está bien, intentemos enviar un SMS de prueba (reemplace <code>1234567</code> con el número destino apropiado):
<pre style="background:#000;color:#fff">
wget 'http://127.0.0.1:13013/cgi-bin/sendsms?username=&password=&to=1234567&text=Hola'
</pre>
<p>Generalmente es posible enviar el SMS a uno mismo, especificando el número de teléfono propio como número de destino. Esto puede ser útil si no se dispone de otra línea para hacer pruebas. En este ejemplo, no estamos especificando un nombre de usuario y contraseña para enviar el SMS porque configuramos un nombre de usuario vacío en <i>kannel.conf</i>. Omitir la autenticación de usuario, como hacemos en este ejemplo, no es recomendable para los servicios productivos.
<p>Intentemos enviar un SMS con formato Unicode con algún emoji. Nótese que agregamos el parámetro <code>coding=2</code> para activar la codificación Unicode:
<pre style="background:#000;color:#fff">
wget 'http://127.0.0.1:13013/cgi-bin/sendsms?username=&password=&to=1234567&coding=2&text=%D8%3D%DE%00'
</pre>
<p>El valor correspondiente en hexadecimal para diferentes emoticonos y emoji se puede encontrar en <a href="https://www.celersms.com/emo-es.html">esta tabla</a> (consulte la columna UTF16). Para mayor información acerca de la codificación de SMS con emoticonos y emoji puede consultar <a href="https://www.celersms.com/emosms-es.htm">este artículo</a>.
<p>Si el envío de SMS funciona correctamente, lo siguiente que podemos probar es el servicio de respuesta automática. Este servicio producirá una respuesta cuando el SMS entrante tenga la palabra clave “SI” o “NO”. Un caso de uso más realista invocaría una URL de un servicio web para procesar los SMS que coincidan con el filtro que se tiene configurado. Por ejemplo:
<pre>
<b>group</b> = sms-service
<b>keyword-regex</b> = ^(?i)(si|no)$
<b>catch-all</b> = 1
<b>get-url</b> = "http://127.0.0.1:13013/cgi-bin/sendsms?username=&password=&to=%p&text=Mensaje+recibido+(%t)"
<b>max-messages</b> = 0
</pre>
<p>La configuración anterior utiliza la API de <code>sendsms</code> para enviar la respuesta. El resultado será el mismo que antes. Sin embargo, en este caso puede configurar su propio servicio web para procesar estos mensajes e implementar escenarios más complejos y personalizados. Tenga en cuenta que en este caso <code>max-messages</code> se deja en cero para evitar que se produzcan dos respuestas.
<p>Kannel soporta muchas funcionalidades avanzadas y diferentes tipos de mensajes. Todos estos casos de uso están cubiertos en la <a href="https://www.kannel.org/doc.shtml" target="_blank">documentación oficial</a>. Además, la app <b>SMS Proxy Pro</b> se puede utilizar para enviar SMS binarios, si el dispositivo Android es compatible con esta función. Los SMS binarios se pueden usar para realizar configuración remota de dispositivos, enviar contenido interactivo, rastrear la ubicación del móvil y mucho más.
<p>&nbsp;
<h4>Referencias</h4>
<p>1. <a href="https://www.etsi.org/deliver/etsi_ts/123000_123099/123040/16.00.00_60/ts_123040v160000p.pdf" target="_blank"><i>«Technical realization of the Short Message Service (Release 16)»</i></a> (en inglés), ETSI (2020)
<p>2. <a href="https://smpp.org/smppv50.pdf" target="_blank"><i>«Short Message Peer-to-Peer Protocol Specification Version 5.0»</i></a> (en inglés), SMS Forum (2003)
<p>3. <a href="https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml" target="_blank"><i>«Service Name and Transport Protocol Port Number Registry»</i></a> (en inglés), Internet Assigned Numbers Authority
<p>&nbsp;
]]></description>
<dc:language>es</dc:language><dc:format>text/html</dc:format><dc:identifier>https://www.celersms.com/sms-reply-back-kannel-es.htm</dc:identifier>
</item>
<item>
	<title>Sistemas Abiertos, pero Seguros</title>
	<pubDate>Fri, 31 Dec 2021 17:21:00 GMT</pubDate><author>admin@celersms.com (Vladimir Kame&#241;ar)</author>
	<link>https://www.celersms.com/open-secure-platforms-es.htm</link><guid isPermaLink="true">https://www.celersms.com/open-secure-platforms-es.htm</guid><description><![CDATA[
<p>Android se posicionó como el sistema operativo móvil más utilizado en el mundo, en gran parte debido a su calidad de sistema abierto. Los sistemas operativos más antiguos, como Symbian, Blackberry OS, Windows Mobile, con los cuales entró a competir Android a mediados de los años 2000, eran sistemas de código cerrado. Google logró cautivar a los desarrolladores ofreciendo una plataforma abierta, personalizable, con herramientas de desarrollo gratuitas.
<p><center><img src="https://www.celersms.com/images/android-security.png" alt="Sistemas Abiertos, pero Seguros"></center>
<p>Existe la opinión de que los sistemas abiertos son menos seguros. Si los hacker tienen acceso a los códigos fuente de los componentes del sistema operativo, entonces no tienen la necesidad de hacer ingeniería inversa en busca de vulnerabilidades. Si las aplicaciones tienen control sobre la mayoría de los recursos del dispositivo, entonces es posible que estos recursos se utilicen en perjuicio de los intereses del usuario. Uno de los grandes retos para Google ha sido mantener Android como una plataforma abierta, pero al mismo tiempo contrarrestar sus posibles desventajas en materia de seguridad.
<p>Tim Cook <a href="https://www.youtube.com/watch?v=RMHclZR6Neo" target="_blank">dijo en <i>VivaTech 2021</i></a> que ha habido 47 veces más incidencias de malware en Android que en iOS. Panda Security había publicado una <a href="https://www.pandasecurity.com/en/mediacenter/mobile-security/android-more-infected-than-ios/" target="_blank" rel=“nofollow”>métrica similar en 2019</a>, indicando que los casos de malware en Android son cerca de 50 veces más frecuentes que en iOS.
<p>En realidad, estas cifras no son tan desfavorables para Android, como podría parecer a primera vista. Estas métricas abarcan teléfonos <i>rooteados</i> y versiones de Android muy antiguas, en las cuales los niveles de seguridad eran mínimos. Además, si Android es tan popular entre los desarrolladores, también lo es entre los hacker y los autores de malware.
<p>Algunos de los sistemas operativos más seguros corresponden a la familia BSD: OpenBSD, NetBSD, FreeBSD.<sup>1</sup> Estos sistemas operativos son abiertos, pero aun así son más seguros que muchos de los sistemas operativos cerrados.
<p>Una de las ventajas del código fuente abierto, desde el punto de vista de seguridad, es que los expertos en seguridad pueden estudiar este código. Esto no solo ayuda a identificar y corregir posibles vulnerabilidades. También permite detectar patrones de diseño que conducen a la ocurrencia de vulnerabilidades futuras.<sup>2</sup>
<p>&nbsp;
<h4>Permisividad vs. inseguridad</h4>
<p>Las primeras versiones de Android tenían controles de seguridad mínimos. Las aplicaciones podían acceder a todos los datos del usuario y el teléfono. Desde el punto de vista del desarrollador esto era una gran ventaja en comparación con otros sistemas operativos, pero al mismo tiempo provocó que los fabricantes de teléfonos (Samsung, HTC, Sony, etc.) comenzaran a personalizar sus versiones de Android, eliminando las funcionalidades más peligrosas o restringiendo el acceso a las mismas.
<p>Google también comenzó a eliminar las funcionalidades que representaban mayor riesgo. Por ejemplo, uno de los cambios polémicos fue la eliminación de la API <code>sendRawPdu</code> <a href="https://issuetracker.google.com/issues/36917186" target="_blank">en Android 2.x</a>, sin explicación oficial de parte de Google y sin alternativa que no implique <i>rooteo</i> del dispositivo. Esta API era usada por las aplicaciones para enviar SMS binarios.
<p>La primera generación de Android permitió evidenciar un conflicto de intereses. Por una parte, Google deseaba que Android se convirtiera en la plataforma móvil más utilizado, desplazando a la competencia. Por otra parte, Google no podía permitir que los desarrolladores tuvieran control total sobre el dispositivo, ya que esto último hacía inviable el uso comercial masivo de Android.
<p>En este punto se vuelve evidente que la vulnerabilidad original de Android se debió a su permisividad (falta de restricciones para acceder a los recursos, datos o funcionalidades sensibles), no al hecho de que el sistema fuese abierto. Esta permisividad comenzó a desaparecer en las versiones subsiguientes. Las versiones más actuales tienen niveles de permisividad comparables con los de otros sistemas operativos, no solamente móviles. Por ejemplo, Android 8 introdujo restricciones para las aplicaciones que se ejecutan <a href="https://developer.android.com/about/versions/oreo/background" target="_blank">en segundo plano</a>. Estas restricciones ayudan a ahorrar el uso de batería, datos y otros recursos, por parte de los procesos que no son visibles para el usuario. Otro ejemplo de reducción de permisividad son las restricciones para el acceso a la SIM a partir de Android 2.x. Actualmente solamente las aplicaciones del sistema y las aplicaciones con privilegios de operador pueden interactuar directamente con la SIM.
<p>Cada nueva versión de Android introduce restricciones adicionales. Esto obliga a los desarrolladores a modificar su código para adaptarse a las restricciones nuevas. En algunos casos no es posible encontrar una alternativa equivalente, como en el ejemplo de <code>sendRawPdu</code> mencionado más arriba. Por lo tanto, cualquier aplicación que hace uso de recursos sensibles puede volverse obsoleta en una futura versión de Android.
<p>&nbsp;
<h4>Diferentes sabores de Android</h4>
<p>Por ejemplo, un teléfono de marca Samsung y otro teléfono de marca Huawei pueden tener la misma versión de Android, pero las plataformas no son idénticas. Como se mencionó más arriba, los fabricantes de teléfonos comenzaron a personalizar sus propias distribuciones, conocidas como <a href="https://en.wikipedia.org/wiki/Custom_ROM" target="_blank"><i>Custom ROM</i></a>, prácticamente a partir de las primeras versiones de Android.
<p><center><img src="https://www.celersms.com/images/android-different-flavours.png" alt="Diferentes sabores de Android"></center>
<p>Las versiones genéricas, publicadas y mantenidas por Google, son conocidas como <a href="https://source.android.com/" target="_blank">AOSP</a> (en inglés, <i>Android Open Source Project</i>). Estas versiones son usadas en los dispositivos producidos por Google y otros dispositivos genéricos, generalmente de bajo costo.
<p>Las versiones personalizadas pueden incluir cambios cosméticos, ya que las primeras versiones genéricas no contaban con interfaces gráficas particularmente atractivas. Por ejemplo, los dispositivos de gama alta fabricados por HTC incluían unas mejoras de interfaz de usuario conocidas como <i>Sense</i>. Las versiones personalizadas también pueden incluir cambios en el <i>kernel</i> (núcleo) para soportar mejor el hardware del dispositivo. Esto permite mejorar el rendimiento y aprovechar mejor los recursos del dispositivo. El hardware es bastante heterogéneo, por lo que la versión AOSP no siempre logra tener compatibilidad y aprovechar el hardware de la mejor forma posible. Por ejemplo, algunos fabricantes incluyen termovisor, lector RFID, impresora, entre otros ejemplos de dispositivos que no son de uso común en los teléfonos móviles. Para soportar estas funcionalidades añadidas también puede ser necesario personalizar Android.
<p>Las versiones personalizadas pueden ser más seguras o menos seguras. Por ejemplo, algunos operadores preinstalan aplicaciones, las cuales permiten agregar aplicaciones adicionales sin el consentimiento del usuario. Esto compromete la privacidad y seguridad del usuario. Además, estos mecanismos de instalación automática de apps pueden ser explotados para difundir malware, burlando todas las restricciones de seguridad del dispositivo.
<p>En resumen, no todos los Android son iguales. Por lo tanto, resulta sorprendente que diferentes fuentes generalicen el concepto de seguridad en Android sin hacen un estudio comparativo de diferentes versiones y personalizaciones existentes.
<p>&nbsp;
<h4>Un reto para el desarrollador</h4>
<p>El desarrollador Android puede elegir que su aplicación solamente funcione en dispositivos no <i>rooteados</i> con las últimas versiones de Android disponibles. Algunos desarrolladores de servicios bancarios y afines toman esta decisión para reducir los riesgos de vulnerabilidades. Ingresar al banco desde un teléfono muy viejo puede ser como acceder desde un computador público. El riesgo de comprometer la seguridad por cuenta de un programa espía puede ser muy alto.
<p>Por otra parte, soportar una mayor variedad de dispositivos, incluyendo los más antiguos, permite alcanzar una mayor base de usuarios.
<p>En caso de que el usuario llegue a ser víctima de fraude, la responsabilidad no va a ser del fabricante del teléfono, el sistema operativo o el operador móvil. El desarrollador de la app será señalado como responsable. Por lo tanto, es muy importante evaluar los riesgos antes de publicar la aplicación.
<p>&nbsp;
<h4>Referencias</h4>
<p>1. Michael W. Lucas (2013), <a href="https://books.google.com/books?id=WAYvDwAAQBAJ" target="_blank"><i>«Absolute OpenBSD: Unix for the practical paranoid»</i></a> (en inglés), 2ª ed, No Starch Press. ISBN 978-1-59327-476-4
<p>2. Amiangshu Bosu, Jeffrey C. Carver et al (2014). <a href="https://www.researchgate.net/publication/286718581_When_Are_OSS_Developers_More_Likely_to_Introduce_Vulnerable_Code_Changes_A_Case_Study" target="_blank"><i>«When are OSS Developers More Likely to Introduce Vulnerable Code Changes? A Case Study.»</i></a> (en inglés), IFIP International Conference on Open Source Systems, DOI:10.1007/978-3-642-55128-4_37
<p>&nbsp;
]]></description>
<dc:language>es</dc:language><dc:format>text/html</dc:format><dc:identifier>https://www.celersms.com/open-secure-platforms-es.htm</dc:identifier>
</item>
<item>
	<title>Tarjeta SIM como Módulo de Seguridad (HSM)</title>
	<pubDate>Sat, 25 Dec 2021 20:37:00 GMT</pubDate><author>admin@celersms.com (Victor Celer)</author>
	<link>https://www.celersms.com/android-SIM-HSM-es.htm</link><guid isPermaLink="true">https://www.celersms.com/android-SIM-HSM-es.htm</guid><description><![CDATA[
<p>El <a href="https://www.celersms.com/android-permissions-es.htm">artículo anterior</a> expuso que las <i>SIMcard</i> (o <a href="https://es.wikipedia.org/wiki/Tarjeta_SIM" target="_blank">tarjetas SIM</a>) pueden utilizarse para otorgar privilegios de operador. Estos privilegios permiten obtener los permisos más elevados y sensibles en Android, sin recurrir al <a href="https://es.wikipedia.org/wiki/Android_rooting" target="_blank">rooteo</a> del dispositivo. Por lo tanto, resulta evidente que tanto los operadores móviles como los proveedores de los dispositivos Android confían plenamente en la seguridad de la SIM.
<p><center><img src="https://www.celersms.com/images/android-SIM.png" alt="Tarjeta SIM como Módulo de Seguridad (HSM)"></center>
<p>Las SIM son dispositivos creados especialmente para resistir cualquier intento de <i>hackeo</i>. Estos dispositivos incluyen mecanismos de bloqueo automático para proteger la información sensible. Por ejemplo, los equipos de trazado y depuración para SIM pueden costar miles de euros, aunque estos equipos solamente interceptan los datos que viajan entre la SIM y el teléfono, como un <a href="https://es.wikipedia.org/wiki/Analizador_de_paquetes" target="_blank">«sniffer» de red</a>. Estos equipos no permiten clonar las tarjetas o extraer las claves allí almacenadas.
<p>&nbsp;
<h4>Módulos HSM</h4>
<p>Dado que la SIM ofrece un alto nivel de seguridad, mayor que la protección alcanzable por medio de software, existen diferentes casos de uso de SIM en calidad de HSM (en inglés, <a href="https://es.wikipedia.org/wiki/HSM" target="_blank"><i>Hardware Security Module</i></a>). Los módulos HSM son procesadores criptográficos, implementados en hardware, cuyo propósito es la protección de claves criptográficas. Aunque existen emuladores de HSM en software, los módulos HSM físicos pueden ofrecer mayor seguridad. Esto se debe a la imposibilidad de leer la memoria de estos procesadores de manera externa, lo cual hace prácticamente imposible la ingeniería inversa. En cambio, los módulos HSM emulados en software no pueden impedir la lectura de la memoria de manera física. El mismo razonamiento es usado por los fabricantes de SIM para argumentar que los chips físicos son más seguros que las SIM virtuales.
<p><center><img src="https://www.celersms.com/images/SIM-form-factors.png" alt="Mini-SIM, micro-SIM, nano-SIM, eSIM"></center>
<p>No se debe confundir las SIM virtuales con la evolución de <a href="https://es.wikipedia.org/wiki/ESIM" target="_blank">eSIM</a>. Estas últimas virtualizan los datos contenidos en la SIM, pero el dispositivo de almacenamiento sigue siendo un chip físico, el cual protege el acceso a la memoria de la misma manera como la SIM tradicional. Este chip no es removible. Por eso, se dice que eSIM es la versión embebida de SIM.
<p>Las llaves de autenticación de la suscripción móvil se almacenan dentro de la SIM. Sin embargo, la SIM puede almacenar llaves adicionales. Por ejemplo, algunos bancos utilizan esta funcionalidad para cifrar las transacciones electrónicas hechas desde el celular. Las llaves bancarias son diferentes de las llaves de autenticación en la red móvil, pero se almacenan y protegen de la misma manera.
<p>&nbsp;
<h4>Comandos APDU</h4>
<p>La comunicación entre el teléfono y la SIM funciona por medio de comandos <a href="https://es.wikipedia.org/wiki/Application_Protocol_Data_Unit_(electr%C3%B3nica)" target="_blank">APDU</a>, cuyo formato está definido en el estándar <b>ISO/IEC 7816-4</b>.<sup>1</sup>
<p>Tradicionalmente la comunicación es iniciada por el teléfono y se realiza de manera síncrona. Es decir, se espera que la SIM responda antes de enviar el próximo APDU:
<p><center><img src="https://www.celersms.com/images/mobile-SIM-APDU.png" alt="Comunicación con la SIM por medio de comandos APDU"></center>
<p>El comando APDU enviado hacia la SIM incluye un encabezado obligatorio con 4 octetos: CLA, INS, P1 y P2.
<table style="margin-left:auto;margin-right:auto" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr><td style="background-color:#abdff5;text-align:center" width="48">CLA<td width="242">Clase: ETSI, 3GPP, Global Platform<sup>2</sup>
<tr><td style="background-color:#abdff5;text-align:center">INS<td>Código de instrucción
<tr><td style="background-color:#abdff5;text-align:center">P1<td>Parámetro #1
<tr><td style="background-color:#abdff5;text-align:center">P2<td>Parámetro #2
</tbody>
</table>
<p>&nbsp;
<p>El resto del APDU es opcional y puede incluir datos adicionales. Por ejemplo, estos datos adicionales sirven para seleccionar un archivo o un applet dentro de la SIM, enviar datos específicos para dicho applet, etc. El formato de los datos puede ser definido por el desarrollador, pero la longitud del APDU debe ser acorde al estándar ISO/IEC 7816-4.
<p>Al procesar el APDU se produce una respuesta, cuyo formato establece que los 2 últimos octetos, conocidos como SW (en inglés, <i>Status Word</i>), indican el estado del resultado. Generalmente el valor 9000 en hexadecimal corresponde a un resultado exitoso. Veamos un ejemplo de APDU y su respectiva respuesta:
<pre>
>> 00 A4 00 00 02 3F 00
&lt;&lt; 90 00
</pre>
<p>El contenido del APDU puede ser interpretado según el estándar <b>ETSI TS 102.221</b>,<sup>3</sup> como sigue:
<p><center><img src="https://www.celersms.com/images/APDU-SELECT-MF.png" alt="APDU: SELECT MF"></center>
<p>El octeto CLA indica que la instrucción es de clase 3G. El octeto INS indica que se debe ejecutar la instrucción <code>SELECT</code> (seleccionar). Los parámetros 1 y 2 pueden indicar el modo de selección. En este caso se debe seleccionar el directorio de raíz conocido como MF (en inglés, <i>Master File</i>), cuyo identificador es <code>3F00</code>. El octeto L<sub>C</sub>, el cual precede el identificador MF, indica la longitud de los datos adicionales. En este caso son 2 octetos adicionales, ya que el identificador MF ocupa 2 octetos. El directorio de raíz está presente en todos los sistemas de archivos en la SIM. Por lo tanto, este APDU debería funcionar correctamente en cualquier SIM compatible con 3G.
<p>&nbsp;
<h4>Applets JavaCard</h4>
<p>Supongamos que tenemos un applet criptográfico instalado en la SIM, el cual se usa para encriptar datos sensibles. Los applets se identifican por medio de un ID único conocido como AID. Supongamos que el AID de nuestro applet criptográfico de pruebas es <code>01020304050607</code>. Normalmente el AID tiene una longitud mayor, pero por simplicidad supondremos que son solamente estos 7 octetos. Entonces, el APDU para seleccionar dicho applet sería:
<pre>
>> 00 A4 04 00 07 01 02 03 04 05 06 07 00
&lt;&lt; 90 00
</pre>
<p>Luego de seleccionar el applet podemos enviar otro APDU con los datos que deseamos encriptar.
<p>Para mayor información acerca de los applets JavaCard y ejemplos de código se recomienda consultar el sitio oficial de <a href="https://www.oracle.com/java/technologies/java-card/javacard-applet.html" target="_blank">Oracle JavaCard</a>. Los applets más simples pueden ser compilados con las herramientas gratuitas, disponibles en el mismo sitio, e instalados en una SIM de pruebas. La gran mayoría de las SIMs actuales soportan esta tecnología. Nótese que JavaCard es una tecnología basada en Java. El desarrollo de applets JavaCard tiene cierta similitud con el desarrollo de aplicaciones Java, excepto que el manejo de memoria es diferente debido a la escasez de este recurso en las SIM. El formato del bytecode JavaCard también se diferencia del formato de bytecode de JVM, pero estas diferencias son transparentes para el desarrollador.
<p>Los applets JavaCard pueden hacer uso de la tecnología <a href="https://en.wikipedia.org/wiki/SIM_Application_Toolkit" target="_blank"><i>SIM Application Toolkit</i></a>, la cual permite ejecutar comandos proactivos en el teléfono, como enviar SMS, desplegar notificaciones y menú interactivos, entre otras funcionalidades.
<p>&nbsp;
<h4>Envío de APDU por medio de AT+CSIM</h4>
<p>La manera más simple de poner en práctica el material expuesto hasta ahora consiste en utilizar un modem GSM para enviar los APDU por medio de un emulador de terminal, como <i>Hyper Terminal</i> o <i>PuTTY</i>. Con el mismo propósito se puede utilizar la librería gratuita <a href="https://www.celersms.com/CelerCOM-es.htm" target="_blank"><i>CelerCOM</i></a> para Java.
<p><center><img src="https://www.celersms.com/images/GSM-modems-USB.jpg" alt="GSM modems"></center>
<p>De esta manera no es necesario utilizar un dispositivo lector de tarjetas y un software especializado para el envío de APDU. La mayoría de los modem GSM soportan el comando AT llamado <code>AT+CSIM</code>, el cual permite encapsular comandos APDU para la SIM. Internamente Android utiliza este mismo comando para ejecutar los APDU que las aplicaciones envían por medio del servicio <a href="https://developer.android.com/reference/android/telephony/TelephonyManager.html" target="_blank">TelephonyManager</a>.
<p>Por ejemplo, el APDU para seleccionar el directorio raíz MF puede ser enviado de la siguiente manera:
<pre>
AT+CSIM=14,"00a40000023f00"
</pre>
<p>El valor 14 es la longitud del APDU en caracteres.
<p>Si el modem responde con un error genérico como <code>+CME ERROR</code> es posible que el modem no soporte el comando <code>AT+CSIM</code>. La mayoría de los modem GSM soportan este comando. Inclusive es posible utilizar un teléfono Android como modem, pero es más práctico usar un modem GSM para puerto USB.
<p>Estos comandos <code>AT+CSIM</code>, enviados por medio de una terminal hacia el modem GSM, sirven para verificar la validez de los comandos. Se recomienda hacer estas pruebas antes de utilizar los mismos APDU en una aplicación Android.
<p>&nbsp;
<h4>Open Mobile API</h4>
<p>Si ya instalamos el applet JavaCard en la SIM de pruebas y ya validamos los comandos APDU, el siguiente paso es hacer una aplicación Android para interactuar con la SIM.
<p>Android soporta el envío de APDU por medio del servicio <a href="https://developer.android.com/reference/android/telephony/TelephonyManager" target="_blank">TelephonyManager</a> a partir de la versión 5.1. A partir de Android 9 esta funcionalidad está disponible por medio de <a href="https://developer.android.com/reference/android/se/omapi/SEService" target="_blank">SEService</a>. Esta nueva opción se basa en las especificaciones de <b>Open Mobile API v3</b><sup>4</sup> de <i>Trusted Connectivity Alliance</i>, una organización integrada por los fabricantes de SIM, anteriormente conocida como <i>SIMAlliance</i>. Todas estas API requieren permisos elevados. Sin embargo, si estamos usando una SIM de pruebas, podemos instalar el hash de nuestra llave de desarrollo dentro de ARA o ARF para obtener privilegios de operador, como se explicó en el <a href="https://www.celersms.com/android-permissions-es.htm">artículo anterior</a>.
<p>Existen implementaciones alternas, basadas en Open Mobile API. Una de las más conocidas se llama <b>SEEK</b> (en inglés, <i>Secure Element Evaluation Kit</i>).<sup>5</sup> Esta API fue creada por <i>Giesecke &amp; Devrient</i>, uno de los fabricantes de SIMcard.
<p>A continuación veamos un ejemplo que produce el mismo APDU que habíamos probado anteriormente con <code>AT+CSIM</code>, utilizando TelephonyManager:
<pre>
<b>import</b> android.telephony.TelephonyManager;
<b>import</b> android.telephony.IccOpenLogicalChannelResponse;

   TelephonyManager tm = (TelephonyManager)getSystemService("<span style="color:#873600;font-weight:bold">phone</span>");
   IccOpenLogicalChannelResponse resp =
      tm.iccOpenLogicalChannel(
         "<span style="color:#873600;font-weight:bold">01020304050607</span>", <span style="color:#616a6b">// AID</span>
         0                 <span style="color:#616a6b">// p2</span>
   );
   <b>int</b> ch = resp.getChannel();
   <b>if</b>(ch > 0)<b>{
      String</b> sResp =
         tm.iccTransmitApduLogicalChannel(
            ch,
            CLA, INS, P1, P2, P3, DATA
      );
      tm.iccCloseLogicalChannel(ch);
   <b>}</b>
</pre>&nbsp;
<p>Este código intenta seleccionar el applet JavaCard con AID <code>01020304050607</code>. Luego le envía el APDU correspondiente a los parámetros CLA, INS, P1, P2, P3 y DATA. El parámetro P3 es opcional. Si no aplica, se puede especificar un valor negativo para que el APDU se envíe solamente con los 4 octetos de CLA, INS, P1 y P2.
<p>A veces, la SIMcard responde con SW <code>61XX</code>. Es decir, el penúltimo octeto de la respuesta tiene el valor hexadecimal 61. Esto significa que el APDU no puede ser procesado por el momento, pero se puede reintentar. Una implementación robusta debería procesar estas respuestas <code>61XX</code> y generar al menos un reintento de envío del mismo APDU. Es importante limitar los reintentos para no saturar la SIM y evitar un bloqueo indefinido. Un único reintento puede ser suficiente.
<p>No olvide implementar manejo de errores. El anterior código debería quedar encerrado en un bloque try/catch. Además, es importante recordar que estas API de TelephonyManager requieren el permiso <a href="https://developer.android.com/reference/android/Manifest.permission#MODIFY_PHONE_STATE" target="_blank">MODIFY_PHONE_STATE</a>. Este permiso puede ser obtenidos en tiempo de instalación solamente hasta Android 2.2. A partir de Android 2.3 este permiso se puede obtener únicamente por las aplicaciones del sistema (preinstaladas) o por medio de privilegios de operador. Esta última opción es la más recomendada, como se había explicado más arriba.
<p>A continuación se presenta otro ejemplo, utilizando Open Mobile API:
<pre>
<b>import</b> android.se.omapi.SEService;
<b>import</b> android.se.omapi.Session;
<b>import</b> android.se.omapi.Channel;
<b>import</b> android.se.omapi.Reader;
<b>import</b> java.util.concurrent.Executors;

   ExecutorService exe = Executors.newSingleThreadExecutor();
   SEService se = <b>new</b> SEService(
      <b>this</b>, <span style="color:#616a6b">// context</span>
      exe,  <span style="color:#616a6b">// para procesar los callback</span>
      <b>this</b>  <span style="color:#616a6b">// listener</span>
   );
   Reader[] readers = se.getReaders();
   <b>if</b>(readers.length > 0)<b>{</b>
      Session sess = readers[0].openSession();
      Channel ch = sess.openLogicalChannel(
         <span style="color:#616a6b">// AID</span>
         <b>new byte</b>[]{ 1, 2, 3, 4, 5, 6, 7 },
         0 <span style="color:#616a6b">// p2</span>
      );
      <b>byte</b>[] respApdu = ch.transmit(
         <b>new byte</b>[]{ <span style="color:#616a6b">/* APDU */</span> }
      );
      ch.close();
   <b>}</b>
</pre>&nbsp;
<p>Nótese que en este caso los APDU son codificados como arreglos de bytes, no cadenas de texto hexadecimales. Otra diferencia importante es que la API puede manejar los reintentos de envío de APDU automáticamente, por lo que no es necesario procesar las respuestas con SW <code>61XX</code>.
<p>En este caso también se recomienda agregar un bloque try/catch para manejo de errores. Uno de los errores posibles es la ausencia de permisos.
<p>Adicionalmente, se puede combinar los ejemplos de <code>TelefonyManager</code> y <code>SEService</code> para implementar una solución compatible con diferentes versiones de Android.
<p>&nbsp;
<h4>Conclusiones</h4>
<p>La SIM, como módulo de seguridad, puede ser útil para almacenar datos sensibles, implementar servicios de encripción y desencripción, entre otros usos. La ventaja principal tiene que ver con la seguridad física de la SIM.
<p>Las aplicaciones Android requieren permisos elevados para poder interactuar con la SIM. Para obtener estos permisos se recomienda hacer uso de los privilegios de operador, los cuales pueden ser otorgados por medio de la misma SIM.
<p>Existen diferentes API para interactuar con la SIM en Android. La disponibilidad de estas API depende del fabricante y la versión del sistema operativo. Es posible combinar las API para soportar múltiples versiones de Android.
<p>&nbsp;
<h4>Referencias</h4>
<p>1. <a href="https://www.iso.org/standard/36134.html" target="_blank"><i>«ISO/IEC 7816-4»</i></a> (en inglés), ISO/IEC JTC 1/SC 17 (2005)
<p>2. <a href="https://globalplatform.org/wp-content/uploads/2018/05/GPC_CardSpecification_v2.3.1_PublicRelease_CC.pdf" target="_blank"><i>«Global Platform Technology Card Specification v2.3.1»</i></a> (en inglés), Global Platform (2018)
<p>3. <a href="https://www.etsi.org/deliver/etsi_ts/102200_102299/102221/15.00.00_60/ts_102221v150000p.pdf" target="_blank"><i>«Smart Cards; UICC-Terminal interface; Physical and logical characteristics (Release 15)»</i></a> (en inglés), ETSI (2018)
<p>4. <a href="https://trustedconnectivityalliance.org/technology-library-sim-specifications/" target="_blank"><i>«Open Mobile API v3.0»</i></a> (en inglés), Trusted Connectivity Alliance (2016)
<p>5. Michael Roland, Michael Hölzl (2016). <a href="https://arxiv.org/ftp/arxiv/papers/1601/1601.03027.pdf" target="_blank"><i>«Open Mobile API: Accessing the UICC on Android Devices»</i></a> (en inglés), University of Applied Sciences Upper Austria.
<p>&nbsp;
]]></description>
<dc:language>es</dc:language><dc:format>text/html</dc:format><dc:identifier>https://www.celersms.com/android-SIM-HSM-es.htm</dc:identifier>
</item>
<item>
	<title>Control de Permisos Android</title>
	<pubDate>Fri, 03 Dec 2021 18:23:00 GMT</pubDate><author>admin@celersms.com (Victor Celer)</author>
	<link>https://www.celersms.com/android-permissions-es.htm</link><guid isPermaLink="true">https://www.celersms.com/android-permissions-es.htm</guid><description><![CDATA[
<p>El control de permisos en las primeras versiones de Android consistía únicamente en declarar dichos permisos dentro de <i>AndroidManifest.xml</i>. Hoy en día se mantiene la misma modalidad para los permisos menos ofensivos. En cambio, los permisos más sensibles, como el acceso a la ubicación, requieren aprobación expresa de parte del usuario. Algunos permisos, como el envío de SMS, requieren aprobación selectiva por parte del equipo de Google Play para la publicación en línea. Además, los aplicativos firmados por el operador móvil tienen mayores privilegios. Esto se conoce como privilegios de operador y se usa para configurar el dispositivo (por ejemplo, los servicios de VoLTE). Los permisos pueden funcionar de manera temporal o permanente. Además, algunos permisos pueden funcionar de manera diferente si el servicio se encuentra en segundo plano.
<p><center><img src="https://www.celersms.com/images/android-permissions.png" alt="Control de Permisos Android"></center>
<p>&nbsp;
<h4>Permisos de tiempo de instalación</h4>
<p>Los permisos de tiempo de instalación, como su nombre lo indica, se otorgan en el momento de la instalación de la aplicación. Un ejemplo de permiso de tiempo de instalación es el permiso para acceder a internet.
<p>Para hacer uso de un permiso de tiempo de instalación simplemente se debe declarar dicho permiso en <i>AndroidManifest.xml</i>, por ejemplo:
<pre>
&lt;uses-permission android:name="<span style="color:#873600;font-weight:bold">android.permission.INTERNET</span>"/>
&lt;uses-permission android:name="<span style="color:#873600;font-weight:bold">android.permission.READ_EXTERNAL_STORAGE</span>"/>
</pre>&nbsp;
<p>Estos permisos son visibles para el usuario en la tienda en línea. Sin embargo, muchas veces el usuario no presta atención a estos permisos durante la instalación de la app. Por eso, los permisos que se obtienen de esta manera tienen un nivel de impacto bajo desde el punto de vista de seguridad.
<p>Los permisos de tiempo de instalación se adjudican de manera permanente.
<p>&nbsp;
<h4>Permisos de tiempo de ejecución</h4>
<p>En cambio, los permisos más sensibles requieren acciones adicionales a la declaración dentro del XML. Un ejemplo son los permisos de localización:
<pre>
&lt;uses-permission android:name="<span style="color:#873600;font-weight:bold">android.permission.ACCESS_COARSE_LOCATION</span>"/>
&lt;uses-permission android:name="<span style="color:#873600;font-weight:bold">android.permission.ACCESS_FINE_LOCATION</span>"/>
</pre>&nbsp;
<p>El permiso <code>ACCESS_COARSE_LOCATION</code> aplica para las apps que requieren acceso a la localización aproximada del dispositivo. La localización aproximada generalmente se obtiene por medio de los servicios de red. En cambio, el permiso <code>ACCESS_FINE_LOCATION</code> se usa para obtener la localización precisa, la cual generalmente hace referencia a GPS. Google recomienda incluir ambos permisos para que el usuario pueda decidir si se aplica la localización aproximada o precisa, lo cual es posible <a href="https://developer.android.com/training/location/permissions" target="_blank">a partir de Android 12</a>.
<p>Sin embargo, solamente declarar estos permisos no es suficiente. A partir de Android 6 se debe solicitar estos permisos en tiempo de ejecución. De esta manera el usuario tiene mayor conciencia de los permisos sensibles y puede no autorizarlos.
<p>Google recomienda utilizar las clases auxiliares <code>ContextCompat</code> y <code>ActivityCompat</code> para validar y solicitar los permisos en tiempo de ejecución. Por ejemplo:
<pre>
<b>import</b> androidx.core.content.ContextCompat;
<b>import</b> androidx.core.app.ActivityCompat;

<b>String</b> COARSE = "<span style="color:#873600;font-weight:bold">android.permission.ACCESS_COARSE_LOCATION</span>";
<b>String</b> FINE = "<span style="color:#873600;font-weight:bold">android.permission.ACCESS_FINE_LOCATION</span>";
<b>int</b> LOCRESULT = 123;

Context ctx = getApplicationContext();
<b>if</b>(ContextCompat.checkSelfPermission(ctx, FINE) != 0 &&
   ContextCompat.checkSelfPermission(ctx, COARSE) != 0)<b>{</b>
   ActivityCompat.requestPermissions(<b>this</b>,
      <b>new String</b>[]{ FINE }, LOCRESULT);
<b>}</b>
</pre>&nbsp;
<p>Este código verifica si alguno de estos 2 permisos ya se encuentra aprobado. En caso contrario se despliega un cuadro solicitando que el usuario conceda los permisos. Nótese que la verificación de permisos se realiza sobre el contexto asociado con el proceso, en el cual se está ejecutando la aplicación. Esto es porque internamente Android asocia los permisos con el ID de proceso (PID) y el ID de usuario (UID). En cambio, la solicitud de permisos recibe un parámetro que representa la actividad (<code>Activity</code>) actual, ya que puede desplegar un elemento interactivo para que el usuario apruebe la solicitud. Cuando el usuario apruebe o desapruebe la solicitud de permisos, se invocará el método <code>onRequestPermissionsResult</code> sobre esta misma actividad:
<pre>
<i>@Override</i>
<b>public void</b> onRequestPermissionsResult<b>(
   int</b> req, <b>String</b> perms[], <b>int</b>[] res)<b>{
   if</b>(req == LOCRESULT
      && res.length > 0 && res[0] == 0)<b>{</b>
      <span style="color:#616a6b">// permisos concedidos</span>
   <b>}
}</b>
</pre>&nbsp;
<p>Es opcional procesar la notificación del resultado. La aprobación se realiza de manera asíncrona. Por lo tanto, procesar la notificación permite implementar una lógica condicional según la decisión del usuario. Por ejemplo, si el usuario decide no aprobar los permisos, la aplicación podría desplegar un mensaje de error o implementar una funcionalidad alterna.
<p>Si no desea utilizar librerías auxiliares <b>AndroidX</b> (<a href="https://developer.android.com/jetpack/androidx" target="_blank"><i>Android Extension Library</i></a>), es posible implementar la misma lógica por medio de las API estándar de Android. Esta opción no es recomendada por Google y podría dejar de funcionar en alguna versión futura de Android.
<pre>
<b>import</b> android.os.Process;
<b>import</b> android.app.Activity;

<b>String</b> COARSE = "<span style="color:#873600;font-weight:bold">android.permission.ACCESS_COARSE_LOCATION</span>";
<b>String</b> FINE = "<span style="color:#873600;font-weight:bold">android.permission.ACCESS_FINE_LOCATION</span>";
<b>int</b> LOCRESULT = 123;

<b>int</b> pid = Process.myPid(), uid = Process.myUid();
<b>if</b>(checkPermission(FINE, pid, uid) != 0 &&
   checkPermission(COARSE, pid, uid) != 0)<b>{</b>
      requestPermissions(<b>new String</b>[]{ FINE }, LOCRESULT);
<b>}</b>
</pre>&nbsp;
<p>En ambos casos es importante agregar la verificación de versión de SDK y un manejo mínimo de errores con un bloque try/catch, como sigue:
<pre>
<b>if</b>(Build.VERSION.SDK_INT > 22)<b>{
   try{</b>
     <span style="color:#616a6b">// verificar permisos de localización</span>
   <b>}catch</b>(Exception exc)<b>{</b>
      Log.e("<span style="color:#873600;font-weight:bold">App</span>", "<span style="color:#873600;font-weight:bold">exception</span>", exc);
   <b>}</b>
}
</pre>&nbsp;
<p>De esta manera, el código de validación de permisos se ejecuta solamente en Android 6 o posterior (SDK mayor que 22), ya que en versiones anteriores estos permisos eran otorgados en tiempo de instalación.
<p>Recuerde que a partir de Android 12 se recomienda separar los permisos de localización aproximada y localización precisa para que el usuario pueda elegir uno de los 2 métodos, ambos o ninguno.
<p>Para habilitar otros permisos de tiempo de ejecución se utiliza la misma metodología. Previo a la solicitud de los permisos, se recomienda desplegar un cuadro informativo explicando por qué se requieren dichos permisos. Esto ayuda a convencer al usuario para que no bloquee los permisos.
<p>Los permisos de tiempo de ejecución pueden ser revocados automáticamente, luego de un período de inactividad. Esto sucede a partir de Android 11. Si la app deja de utilizarse durante un tiempo largo (varios meses), los permisos pueden ser <a href="https://developer.android.com/about/versions/11/privacy/permissions" target="_blank">revocados automáticamente</a>. Por lo tanto, la aplicación debe verificar los permisos cada vez que los va a utilizar.
<p>&nbsp;
<h4>Privilegios de operador</h4>
<p>A partir de Android 5.1 se introdujo una funcionalidad conocida como privilegios de operador (en inglés, <a href="https://source.android.com/devices/tech/config/uicc" target="_blank"><i>Carrier Privileges</i></a>). Esta funcionalidad permite otorgar permisos especiales para las aplicaciones cuya firma digital concuerda con la lista de firmas instaladas en la SIMcard. Se asume que solamente el operador móvil o el fabricante de la SIMcard pueden modificar la lista de firmas en la SIMcard. Un proveedor de aplicaciones independiente no tiene acceso a las llaves administrativas de la SIMcard. Por lo tanto, no puede manipular la lista de firmas.
<p>Lo que se almacena en la SIMcard es un valor hash (SHA1) de la clave, no la clave misma. Opcionalmente, junto con este hash, se puede incluir el nombre del paquete de la aplicación, correspondiente al parámetro <code>package</code> dentro de <i>AndroidManifest.xml</i>. Esto puede ser útil si la misma firma se usa en múltiples aplicaciones, pero los privilegios de operador son requeridos solamente en algunas.
<p>Existen 2 métodos para almacenar la lista de firmas en la SIMcard:
<p>&#x2022; Por medio de un aplicativo llamado ARA, el cual se ejecuta dentro de la SIMcard. Este aplicativo se encuentra definido en el estándar <b>GPD_SPE_013</b>.<sup>1</sup>
<p>&#x2022; Dentro de un archivo llamado ARF definido en el estándar <b>PKCS #15</b>.<sup>2</sup>
<p>ARF es soportado a partir de Android 7 y se usa si no se encuentra ARA. Dado que ARA tiene prioridad y es soportado a partir de Android 5.1, este método es más usado que ARF.
<p>Actualmente la gran mayoría de las SIMcard soportan los estándares <i>Global Platform</i>. Esto no garantiza que el aplicativo ARA se encuentre disponible en todas las SIMcard, ya que no todos los operadores hacen uso de esta funcionalidad. Una versión de ARA de código abierto se puede encontrar aquí:
<table style="margin-left:auto;margin-right:auto;border:1px solid #1f4e79" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="68"><a href="https://github.com/bertrandmartel/aram-applet" target="_blank"><img src="https://www.celersms.com/static/github.png" alt="GitHub" align="left" hspace=10 border=0></a></td>
<td width="275"><div style="padding:5px">El aplicativo <a href="https://github.com/bertrandmartel/aram-applet" target="_blank"><b>ARA-M</b></a> de Bertrand Martel es gratuito y compatible con la mayoría de las SIMcard.</div></td>
</tr>
</tbody>
</table>
<p>&nbsp;
<p>Los operadores móviles acostumbran utilizar versiones de ARA suministradas por los fabricantes de SIMcard. Una de las razones es que los aplicativos genéricos pueden ocasionar uso intensivo de la memoria no volátil de la SIMcard, lo cual acorta su vida útil.
<table style="margin-left:auto;margin-right:auto;border:1px solid #1f4e79" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="68"><a href="https://github.com/herlesupreeth/CoIMS_Wiki" target="_blank"><img src="https://www.celersms.com/static/github.png" alt="GitHub" align="left" hspace=10 border=0></a></td>
<td width="275"><div style="padding:5px">El proyecto <a href="https://github.com/herlesupreeth/CoIMS_Wiki" target="_blank"><b>CoIMS</b></a> contiene una guía para instalar ARA-M. Además, incluye consejos para depurar errores comunes.</div></td>
</tr>
</tbody>
</table>
<p>&nbsp;
<p>Para instalar un aplicativo en la SIMcard se debe contar con las llaves administrativas. El dilema está en que las SIMcard de pruebas, las cuales se comercializan para propósitos de ingeniería e incluyen llaves administrativas, generalmente no incluyen suscripción móvil. En cambio, las SIMcard que ofrecen los operadores móviles no incluyen llaves administrativas. Por lo tanto, las posibilidades de utilizar esta tecnología con una suscripción móvil real son limitadas. Generalmente se requiere una cooperación estrecha con el operador móvil para lograr aprovisionar las firmas del desarrollador en las SIMcard de los usuarios móviles.
<p>A continuación se presenta la lista con algunas funcionalidades disponibles bajo privilegios de operador:
<p>&#x2022; Obtener el ID de la suscripción móvil (IMSI).
<p>&#x2022; Cambiar el nombre del operador.
<p>&#x2022; Activar/desactivar las redes LTE, CDMA, GSM/WCDMA, etc.
<p>&#x2022; Modificar la configuración de <a href="https://es.wikipedia.org/wiki/Subsistema_Multimedia_IP" target="_blank">IMS</a> (ej: VoLTE, VoWiFi).
<p>Una lista más completa puede ser consultada en el sitio oficial de Android para desarrolladores, aunque la lista exhaustiva no es pública. Los privilegios de operador también abarcan los permisos sensibles de tiempo de ejecución, como los permisos para activar o desactivar servicios de datos, bloquear redes, seleccionar la red móvil actual de manera manual o automática, intercambiar comandos APDU con la SIMcard, etc. En el <a href="https://www.celersms.com/android-SIM-HSM-es.htm">siguiente artículo</a> profundizaremos en este último caso de uso.
<p>Dentro de la app Android no se requiere ningún código adicional para hacer uso de los privilegios de operador. Estos privilegios son otorgados automáticamente si la SIMcard contiene el hash de la llave, con la cual se encuentra firmada la app, y opcionalmente el nombre del paquete de la app. Los privilegios también se revocan automáticamente si la SIMcard es removida.
<p>Los privilegios de operador funcionan aun sin registro en la red móvil. También funcionan en modo avión. Si el teléfono soporta dual-SIM o multi-SIM, Android intenta escanear las firmas de ARA o ARF en todas las SIMcard disponibles.
<p>&nbsp;
<h4>Conclusiones</h4>
<p>El manejo de permisos Android ha evolucionado y se ha vuelto cada vez más restrictivo. Aunque Android es un sistema operativo abierto, no todos los aspectos en el manejo de los permisos son públicos y están documentados.
<p>Si tiene la necesidad de utilizar permisos sensibles y no puede obtener dichos permisos para la versión de Android más actual, es posible que en una versión más antigua la obtención de los mismos permisos sea menos restrictiva. Por ejemplo, la lectura del ID de la suscripción (IMSI) en Android 1.6 se podía hacer simplemente declarando el permiso <code>READ_PHONE_STATE</code> dentro del archivo <i>AndroidManifest.xml</i>.
<p>Si está desarrollando una aplicación de uso masivo, es importante reducir el uso de permisos, especialmente los permisos sensibles. No hacerlo incrementa los riesgos de seguridad, por lo que también afecta la permanencia de la aplicación en las tiendas en línea como Google Play.
<p>&nbsp;
<h4>Referencias</h4>
<p>1. <a href="https://globalplatform.org/specs-library/secure-element-access-control-v1-1/" target="_blank"><i>«Secure Element Access Control v1.1»</i></a> (en inglés), Global Platform (2014)
<p>2. <i>«Cryptographic Token Information Format Standard v1.1»</i> (en inglés), RSA Laboratories (1999)
<p>&nbsp;
]]></description>
<dc:language>es</dc:language><dc:format>text/html</dc:format><dc:identifier>https://www.celersms.com/android-permissions-es.htm</dc:identifier>
</item>
<item>
	<title>Seguridad vs. Usabilidad en las Apps Android</title>
	<pubDate>Thu, 25 Nov 2021 21:20:05 GMT</pubDate><author>admin@celersms.com (Miguel Angel Cano)</author>
	<link>https://www.celersms.com/android-security-vs-usability-es.htm</link><guid isPermaLink="true">https://www.celersms.com/android-security-vs-usability-es.htm</guid><description><![CDATA[
<p>Uno de los dilemas en el desarrollo de apps es el balance entre la facilidad de uso y la carga funcional. Esta última representa el conjunto de los casos de uso que ofrece la aplicación. Entre más grande el conjunto, más compleja la interacción con el usuario.
<p>Muchas de las funciones de seguridad, como la autenticación del usuario o la confirmación de una operación sensible, implican acciones adicionales que el usuario debe realizar. Estas acciones pueden ser la lectura de la huella dactilar, el ingreso de una clave, etc. Estas acciones también son parte de la carga funcional y afectan la <a href="https://www.fundeu.es/consulta/usabilidad-2438/" target="_blank">usabilidad</a> de la aplicación.
<p><center><img src="https://www.celersms.com/images/security-usability.png" alt="Seguridad vs. usabilidad en las apps Android"></center>
<p>&nbsp;
<h4>¿Qué es una interfaz de usuario intuitiva?</h4>
<p>Los ejemplos de aplicaciones más simples incluyen la linterna y la brújula. La interacción con el usuario es simple porque la funcionalidad de la aplicación es mínima. Probablemente nadie ha tenido que leer un manual para aprender a manipular la linterna o jugar <a href="https://es.wikipedia.org/wiki/Tetris" target="_blank">Tetris</a>. En cambio, la aplicación de configuración de Android tiene centenares de opciones, muchas de las cuales requieren conocimientos técnicos. Lograr que la experiencia de usuario (UX) sea intuitiva en una aplicación compleja es un reto importante, inclusive para los desarrolladores de Google.
<p>Se dice que la interfaz de usuario es intuitiva si el usuario promedio puede comprenderla fácilmente, sin capacitación previa. No se debe confundir los conceptos de interfaz intuitiva e interfaz fácil de usar, aunque muchas veces sean lo mismo. Por ejemplo, ingresar una clave por medio de unas perillas giratorias que simulan la cerradura de una caja fuerte puede ser intuitivo, pero más complejo que usar el teclado numérico para ingresar un PIN.
<p><center><img src="https://www.celersms.com/images/android-app-ui.png" alt="Interfaz intuitiva Android"></center>
<p>Una interfaz de discado con dial rotatorio o <a href="https://es.wikipedia.org/wiki/Disco_de_marcar" target="_blank">disco de marcar</a>, la cual se usó en todos los teléfonos analógicos, es muy simple, pero hoy en día podría no ser intuitiva, ya que muchas personas no han visto o no recuerdan los teléfonos antiguos.
<p>&nbsp;
<h4>Interfaces web-app</h4>
<p>Actualmente es común el uso de interfaces de tipo <i>web-app</i> dentro de las aplicaciones móviles. También se utilizan interfaces híbridas, en las cuales una parte de la interfaz es de tipo web-app y otra parte es nativa. Las interfaces de tipo web-app son generadas por un servidor web remoto y se despliegan dentro de la aplicación de una manera similar a los navegadores web, como Chrome. La popularidad de este tipo de interfaces se debe principalmente a 2 factores, a saber:
<p>&#x2022; Es posible realizar cambios en la interfaz de manera centralizada, sin publicar una nueva versión de la app y esperar que los usuarios descarguen la actualización.
<p>&#x2022; Se puede usar la misma base de código para la interfaz web y la app. Esto reduce los costos de desarrollo y mantenimiento.
<p>Desde el punto de vista de seguridad, las interfaces web-app también pueden tener ventajas:
<p>&#x2022; Si una posible vulnerabilidad puede ser corregida a nivel de web-app, sin modificar el código nativo, el tiempo de mitigación se reduce considerablemente. Por lo tanto, el impacto también se reduce.
<p>&#x2022; Es más difícil <i>hackear</i> una solución que se ejecuta en un servidor remoto, ya que sólo se tiene acceso a la interfaz de usuario de la misma.
<p>Los servidores web no son invulnerables. Una web-app también puede ser insegura. Sin embargo, en general el código que se ejecuta remotamente en la nube puede estar más protegido que el código nativo que se ejecuta localmente.
<p>La experiencia de usuario con las interfaces web-app suele ser menos óptima, ya que la descarga de la interfaz puede tomar un tiempo, especialmente si la conexión de Internet es lenta. El uso de Internet, además de generar un consumo de datos, produce un incremento en el uso de batería en el teléfono. Se recomienda considerar el uso de interfaces web-app solamente si la aplicación implica conectividad, como las aplicaciones bancarias, redes sociales, etc.
<p>&nbsp;
<h4>Seguridad vs. comodidad</h4>
<p>El mayor reto está en mejorar la seguridad de un servicio sin que estas mejoras generen una mala experiencia de usuario. Por ejemplo, el uso de la biometría, como la huella dactilar o reconocimiento facial, en lugar de memorizar claves, es uno de los avances tecnológicos que han mejorado la experiencia de usuario. El uso de biometría no implica desarrollo de complejos algoritmos de inteligencia artificial. Estos algoritmos ya están disponibles a nivel de hardware o <a href="https://developer.android.com/training/sign-in/biometric-auth" target="_blank">sistema operativo del teléfono</a>.
<p>Otro ejemplo son los sistemas de autenticación basados en patrones de comportamiento del usuario.<sup>1</sup> Estos sistemas estudian la manera como el usuario interactúa con el teléfono, lo cual incluye la manipulación de la pantalla táctil (posición, velocidad, ángulo de deslizamiento), frecuencia y duración de uso, entre otras variables. Ya existen implementaciones comerciales con este tipo de sistemas. De hecho, la idea de perfilar el comportamiento del usuario con fines de autenticación no es nueva. Las implementaciones experimentales han existido al menos desde 2016.<sup>2</sup>
<p>Estas implementaciones han demostrado tener una efectividad superior al 75%. Al combinar estos perfiles de comportamiento con otros factores, como biometría y claves tradicionales, se logra un mayor nivel de confiabilidad.
<p>Sin embargo, es importante recordar que los usuarios pueden cambiar sus hábitos. Además, la autenticación es solamente uno de los aspectos que abarca la seguridad de un servicio. La suplantación de la identidad del usuario es solamente uno de los métodos que utilizan los estafadores para cometer fraude. Otros métodos consisten en interceptar los canales de comunicación explotando posibles vulnerabilidades, la ingeniería inversa, etc.
<p>&nbsp;
<h4>El eslabón más débil</h4>
<p>Thomas Reid, filósofo escocés, escribió que <i>«una cadena es tan fuerte como su eslabón más débil»</i>. Esta frase se aplica perfectamente en materia de seguridad informática, incluyendo los servicios móviles. Por lo tanto, es importante auditar constantemente cada uno de los módulos o procesos que intervienen en el servicio. Reducir al mínimo posible los eslabones de la cadena también ayuda a minimizar los riesgos.
<p><center><img src="https://www.celersms.com/images/broken-chain.png" alt="Una cadena es tan fuerte como su eslabón más débil"></center>
<p>El eslabón más débil puede ser el usuario, quien anota su contraseña y la guarda en un lugar visible para no olvidarla. El uso de protocolos poco seguros por compatibilidad con dispositivos antiguos o versiones previas del aplicativo también se puede convertir en una vulnerabilidad.
<p>Un colega que desarrolla drivers para Windows dice que a veces el cambio más inofensivo puede ocasionar efectos desastrosos. El desarrollo de apps también es susceptible a este tipo de situaciones, aunque en menor medida. Un control estricto de cambios y versiones, combinado con pruebas de control de calidad exhaustivas, reducen la probabilidad de errores, incluyendo los errores de seguridad.
<p>En las grandes empresas de software existe el cargo de especialista en seguridad u <a href="https://es.wikipedia.org/wiki/Oficial_de_seguridad_de_la_informaci%C3%B3n" target="_blank">oficial de seguridad de la información</a>. Contar con recursos dedicados a los tema de seguridad ayuda a reducir los riesgos. La seguridad es un aspecto menos visible que la usabilidad o la carga funcional, por lo que no siempre recibe la misma atención durante el ciclo de desarrollo. Además, los desarrolladores no siempre son expertos en seguridad. Por lo tanto, si el equipo de desarrollo no cuenta con especialistas en seguridad, se debe buscar capacitar a los desarrolladores. Muchas de las vulnerabilidades que se detectan en las apps se deben a desconocimiento o descuido.
<p>&nbsp;
<h4>Referencias</h4>
<p>1. Adnan Ali, Vasaki Ponnusamy, Anbuselvan Sangodiah (2019), <a href="https://www.researchgate.net/publication/333285115_User_Behaviour-Based_Mobile_Authentication_System" target="_blank"><i>«User Behaviour-Based Mobile Authentication System»</i></a> (en inglés), DOI:10.1007/978-981-13-6861-5_40
<p>2. Hassan Sbeyti (2016), <a href="https://www.researchgate.net/publication/308522889_Mobile_user_authentication_based_on_user_context_and_behavioral_pattern_MOUBE" target="_blank"><i>«Mobile user authentication based on user context and behavioral pattern (MOUBE)»</i></a> (en inglés), Arab Open University
<p>&nbsp;
]]></description>
<dc:language>es</dc:language><dc:format>text/html</dc:format><dc:identifier>https://www.celersms.com/android-security-vs-usability-es.htm</dc:identifier>
</item>
<item>
	<title>Mitigación de Ingeniería Inversa en Apps Android</title>
	<pubDate>Wed, 07 Jul 2021 16:35:00 GMT</pubDate><author>admin@celersms.com (Victor Celer)</author>
	<link>https://www.celersms.com/reverse-engineering-mitigation-android-es.htm</link><guid isPermaLink="true">https://www.celersms.com/reverse-engineering-mitigation-android-es.htm</guid><description><![CDATA[
<p>No es posible evitar que una aplicación móvil sea descompilada y su funcionamiento interno sea expuesto. El propósito de la ingeniería inversa puede ser el uso ilegal
del aplicativo (piratería informática), explotación de sus posibles vulnerabilidades, entre otros efectos perjudiciales para el desarrollador y los usuarios legales. Existen
métodos de protección, los cuales encriptan el código del aplicativo, pero dicho código eventualmente es desencriptado por el mismo aplicativo para poder ser ejecutado en la
máquina virtual <i>Dalvik</i> de Android. Por eso, el título de este artículo hace referencia a la mitigación, no a la prevención. Los desarrolladores de apps Android,
especialmente las apps comerciales, pueden tomar medidas para que la ingeniería inversa resulte ser más compleja y dispendiosa. De esta manera se logra diferir y minimizar
el impacto. Por ejemplo, si fuera necesario invertir varias semanas de esfuerzo para romper la protección anti-copia de un videojuego, es probable que una nueva versión del
juego sea liberada antes de que se logre piratear la anterior.
<p><center><img src="https://www.celersms.com/images/reverse-eng-android.png" alt="Ingeniería inversa Android"></center>
<p>&nbsp;
<h4>No confíe en las soluciones genéricas</h4>
<p>Un error común consiste en asumir que una protección comercial de tipo DRM o afín puede ser más afectiva que desarrollar un sistema anti-copia propio. El uso de librerías
comerciales para protección de apps puede simplificar la labor de los piratas. Tan pronto se identifique la referencia de la librería comercial, una simple búsqueda en los
foros especializados en ingeniería inversa podrá arrojar los pasos exactos para desactivar dicha protección. En cambio, crear un sistema anti-copia propio puede complicar
mucho más este proceso. Algunas compañías de software han contratado a hacker éticos para crear sus propios sistemas de protección avanzados. Por ejemplo, en los años 2000
la compañía canadiense SSG había contratado los servicios del hacker ético <a href="https://en.wikipedia.org/wiki/Kris_Kaspersky" target="_blank">Kris Kaspersky</a> para
implementar un sistema anti-copia de CD.
<p>Inclusive sin recurrir al conocimiento de los hacker más expertos, es posible implementar mecanismos anti-piratería efectivos. A continuación se comparten recomendaciones
que han demostrado su efectividad en diversos proyectos de apps.
<p>&nbsp;
<h4>La estrategia del señuelo</h4>
<p>Una buena táctica es hacerle creer al <i>reverser</i> (en inglés, <i>reverser</i> hace referencia a quien practica la ingeniería inversa) que el algoritmo es simple.
Por ejemplo:
<pre><b>if</b>(!isRegistered())<b>{</b><br>   Toast.makeText(ctx,<br>      "<span style="color:#873600;font-weight:bold">Error de registro</span>", 0).show();<br>   <span style="color:#616a6b">// ...</span><br><b>}</b><br></pre>&nbsp;
<p>Una manipulación mínima de este código sería suficiente para que la copia pirata del aplicativo funcione como si estuviera debidamente registrada. Eso es lo que debería
de creer quién haya descompilado este código. Lo ideal es que el aplicativo realmente funcione de manera correcta durante algún tiempo. Por ejemplo, la compañía de
videojuegos Aterdux había sacado al mercado un juego con esta misma táctica del señuelo. Los piratas lograron <i>hackearlo</i> rápidamente, pero luego se supo que la versión
pirata funcionaba sólo hasta cierto punto de la campaña del juego. Más adelante se realizaba una nueva comprobación de autenticidad. Entonces, lo que realmente lograron los
piratas fue convertir el juego en una especie de "demo".
<p>La estrategia del señuelo, si se usa de manera inteligente, puede generar una gran frustración en quienes pretenden usar la app de manera ilegal.
<p>&nbsp;
<h4>Trasladar la funcionalidad de la app</h4>
<p>Esto significa alojar de manera externa parte o toda la funcionalidad del aplicativo. El concepto no es nuevo. Por ejemplo, en los años 90 la compañía Rainbow Tech
comenzó a alojar bloques funcionales de aplicativos ejecutables en dispositivos llamados <a href="https://es.wikipedia.org/wiki/Dongle" target="_blank"><i>dongle</i></a>,
los cuales se conectaban al puerto de impresora del PC. La misma idea se aplica hoy en día en los dispositivos de seguridad llamados <i>token</i>. En el caso de un teléfono
móvil la SIMcard puede hacer las veces de <i>token</i>. Es muy difícil replicar la información que se encuentra almacenada en el interior de un dispositivo de seguridad.
Algunos proveedores como Ubirch implementan algoritmos de blockchain utilizando la SIMcard. Esta tecnología se desarrolló para garantizar la autenticidad (ej: el registro
de un usuario en la red celular, la propiedad de una cuenta bancaria, la telemetría, etc.) El mismo principio se puede usar para proteger la licencia de una aplicación.
<p>Sin embargo, puede ser más simple y efectivo trasladar una parte o toda la funcionalidad de la app hacia la nube. La app podría ser una simple interfaz de usuario para
acceder a un servicio que se ejecuta en un servidor en Internet.
<p>Esta estrategia es utilizada por las compañías de desarrollo de software más grandes. Además, se puede decir que las apps de los bancos funcionan de ese modo, ya que las
transacciones son procesadas por los sistemas bancarios en línea.
<p>No en todos los casos puede ser posible que la app tenga acceso a Internet para verificación de autenticidad. Por ejemplo, el acceso a Internet puede ser limitado o
demasiado costoso a bordo de un avión, entre otros medios de transporte. Otro detalle importante a tener en cuenta es que una falla en la nube puede dejar sin servicio a
todos los usuarios legales del aplicativo.
<p>&nbsp;
<h4>Minimizar el impacto</h4>
<p><img align="left" width=88 height=83 src="https://www.celersms.com/images/anti-piracy_android.png" alt="Anti-piratería en Android">Si la app se actualiza
frecuentemente y su costo es bajo, esta app no sería particularmente atractiva para los piratas. Sin embargo, inclusive las apps gratuitas pueden
ser distribuidas ilegalmente. Los piratas pueden contaminar las apps con diferentes tipos de <i>malware</i> para luego sustraer la información personal de los usuarios,
claves, etc.
<p>Se recomienda generar conciencia en los usuarios, explicando los riesgos que conlleva la instalación de apps provenientes de fuentes no oficiales.
<p>&nbsp;
]]></description>
<dc:language>es</dc:language><dc:format>text/html</dc:format><dc:identifier>https://www.celersms.com/reverse-engineering-mitigation-android-es.htm</dc:identifier>
</item>
<item>
	<title>Generación de Identificadores Únicos de Dispositivo Android</title>
	<pubDate>Mon, 31 May 2021 22:41:00 GMT</pubDate><author>admin@celersms.com (Victor Celer)</author>
	<link>https://www.celersms.com/device-id-android-es.htm</link><guid isPermaLink="true">https://www.celersms.com/device-id-android-es.htm</guid><description><![CDATA[
<p>Generar u obtener un único identificador para cada dispositivo donde se instala una app puede ser útil para diferentes propósitos. Por ejemplo,
en un sistema de votación en línea puede ser interesante evitar múltiples votos en un mismo dispositivo. En los sistemas transaccionales los identificadores
únicos sirven para propósitos de trazabilidad. Esto también puede servir para efectos de control de licencias (ej: limitar el número de dispositivos donde
se puede instalar la app).
<p><center><img src="https://www.celersms.com/images/device-id-android.png" alt="Identificadores únicos de dispositivo Android"></center>
<p>&nbsp;
<p>La información personal del usuario, como su número de documento de identidad o número de teléfono, no debería de ser usada para estos
propósitos debido a restricciones de confidencialidad. Tampoco se recomienda el uso de
<a href="https://developer.android.com/training/articles/user-data-ids" target="_blank">identificadores de hardware</a>, como la dirección MAC o el
número IMEI. Una de las razones para evitar el uso de identificadores de hardware en Android es que su obtención requiere permisos elevados.
Además, el número IMEI no siempre es único. Algunos de estos números se repiten a pesar de que
las <a href="http://www.gsma.com/latinamerica/wp-content/uploads/2012/05/IMEI-Database-Overview.pdf" target="_blank">normas de GSMA</a> lo prohíben.
<p>No existe un método que arroje un identificador realmente único en todas las versiones de Android. En este artículo combinamos varios de los
métodos existentes para cubrir la mayoría de los casos de uso. Podemos comenzar con el método más usado que es el "android_id":
<pre>
<b>long</b> uid = 0;<br>String ss;<br><b>try{</b><br>   ss = Secure.getString(ctx, "<span style="color:#873600;font-weight:bold">android_id</span>");<br>   <b>if</b>(ss != null)<b>{</b><br>      uid = new BigInteger(ss, 16).longValue();<br>      <b>if</b>(uid == 0x9774D56D682E549CL)<br>         uid = 0; <span style="color:#616a6b">// filtrar valor no único</span><br>   <b>}</b><br><b>}catch</b>(Exception ex)<b>{</b><br>   Log.e("<span style="color:#873600;font-weight:bold">UID</span>", "<span style="color:#873600;font-weight:bold">error</span>", ex);<br><b>}</b><br>
</pre>&nbsp;
<p>Nótese que este código continúa la ejecución en caso de cualquier error inesperado, incluyendo errores numéricos. Si se obtiene el valor
hexadecimal <b>9774D56D682E549C</b>, este valor es descartado, ya que se conoce que el mismo valor puede ser reportado en
<a href="https://code.google.com/archive/p/odinmobile/wikis/FrequentlyAskedQuestions.wiki" target="_blank">múltiples dispositivos</a>.
<p>Si el anterior código no nos arroja un valor distinto de cero, entonces podemos intentar obtener la dirección MAC de Bluetooth,
suponiendo que la app tiene permisos para usar Bluetooth:
<pre><span style="color:#616a6b">// Desde Android 10 la MAC no puede ser consultada de esta manera</span><br><b>if</b>(uid == 0 && Build.VERSION.SDK_INT &lt;= 28)<b>{</b><br>   ss = null;<br>   <b>try{</b><br>      BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();<br>      <b>try{</b><br>         Field ff = btAdapter.getClass().getDeclaredField("<span style="color:#873600;font-weight:bold">mService</span>");<br>         ff.setAccessible(true);<br>         Object oo = ff.get(btAdapter);<br>         ss = (String)oo.getClass().getDeclaredMethod("<span style="color:#873600;font-weight:bold">getAddress</span>").invoke(oo);<br>      <b>}catch</b>(Throwable th)<b>{</b><br>         ss = btAdapter.getAddress();<br>      <b>}<br>   }catch</b>(Exception ex)<b>{</b><br>      Log.e("<span style="color:#873600;font-weight:bold">UID</span>", "<span style="color:#873600;font-weight:bold">error</span>", ex);<br>   <b>}<br>   if</b>(ss != null)<b>{</b><br><br>      <span style="color:#616a6b">// Convertir MAC a long</span><br>      <b>int</b> bb, vv = 0, xx = 0, yy = ss.length();<br>      <b>boolean</b> pp = <b>false</b>;<br>      <b>while</b>(xx &lt; yy)<b>{<br>         if</b>((bb = (ss.charAt(xx++) | 0x20) - 0x30) > 9)<br>            bb -= 0x27;<br>         <b>if</b>(bb >= 0 && bb &lt;= 0xF)<b>{<br>            if</b>(pp = !pp)<br>               vv = bb &lt;&lt; 4;<br>            <b>else</b><br>               uid = uid &lt;&lt; 8 | vv | bb;<br>         <b>}<br>      }</b><br><br>      <span style="color:#616a6b">// MAC no válida</span><br>      <b>if</b>((<b>int</b>)uid == 0 || uid &lt;= 0 || uid > 0xFFFFFFFFFFFFL)<br>         uid = 0;<br>   <b>}<br>}</b>
</pre>&nbsp;
<p>Si el código anterior tampoco logra obtener un buen valor, entonces una alternativa puede ser tomar la hora exacta con milisegundos,
en la cual se instaló un paquete conocido, como "<i>SystemUI</i>". Este valor no es único, pero puede tener una dispersión y persistencia
razonablemente buenas:
<pre><b>if</b>(uid == 0)<b>{<br>   try{</b><br>      uid = new File(ctx.getPackageManager().getApplicationInfo(<br>         "<span style="color:#873600;font-weight:bold">com.android.systemui</span>", 0).sourceDir).lastModified();<br>   <b>}catch</b>(Exception ex)<b>{</b><br>      Log.e("<span style="color:#873600;font-weight:bold">UID</span>", "<span style="color:#873600;font-weight:bold">error</span>", ex);<br>   <b>}<br>}</b>
</pre>&nbsp;
<p>Una combinación de estos 3 métodos permite cubrir casi la totalidad de los casos de uso. Para evitar colisiones entre los 3 o más métodos
se recomienda acompañar el identificador único con algún indicador que sirva para diferenciar el método utilizado.
<p>Recuerde que no todos los teléfonos tienen Bluetooth. No todos los dispositivos Android son teléfonos y tienen suscripción móvil e IMEI.
No todos los dispositivos Android tienen las mismas apps por defecto disponibles. La diversidad de dispositivos Android genera retos de
desarrollo interesantes. Si omitimos compatibilidad con algún dispositivo o grupo de dispositivos podemos perder un segmento del mercado.
<p>&nbsp;
]]></description>
<dc:language>es</dc:language><dc:format>text/html</dc:format><dc:identifier>https://www.celersms.com/device-id-android-es.htm</dc:identifier>
</item>
<item>
	<title>¿Cómo crear un paquete AAB para Android desde línea de comandos?</title>
	<pubDate>Thu, 04 Mar 2021 19:35:00 GMT</pubDate><author>admin@celersms.com (Vladimir Kame&#241;ar)</author>
	<link>https://www.celersms.com/batch-aab-es.htm</link><guid isPermaLink="true">https://www.celersms.com/batch-aab-es.htm</guid><description><![CDATA[
<p>En un <a href="https://www.celersms.com/batch-apk-es.htm">artículo anterior</a>, aprendimos cómo crear un ejecutable APK para Android desde línea de comandos, sin usar ningún IDE.
Avancemos más y creemos un paquete AAB (<i>Android App Bundle</i>). Sólo utilizaremos JDK, Android SDK y Bundletool. Los pasos que se describen
a continuación se probaron en Windows, pero los mismos comandos se pueden adaptar a cualquier otro entorno.
<p><center><img src="https://www.celersms.com/images/batch-aab.png" alt="Crear un paquete AAB para Android desde línea de comandos"></center>
<p>&nbsp;
<h4>¿Qué es AAB? (<i>Android App Bundle</i>)</h4>
<p>Actualmente, <a href="https://developer.android.com/guide/app-bundle" target="_blank">AAB</a> es el formato preferido para publicar aplicaciones en
Google Play. Este formato de publicación incluye todos los recursos y el código compilado de la aplicación. La generación y la firma del ejecutable APK
se delegan a Google Play. De esta manera, el APK se puede optimizar al incluir sólo el código y los recursos necesarios para un dispositivo específico.
Por lo tanto, el tamaño de la descarga se puede reducir significativamente.
<p>Por ejemplo, supongamos que nuestra aplicación es compatible tanto con teléfonos como con Android TV. Para compatibilidad con Android TV, hemos creado
una imagen de fondo grande de alta resolución. Si publicamos la aplicación en formato APK, nuestra imagen de fondo se descargará en los teléfonos
inteligentes, aunque nunca se usará allí. El formato AAB permite evitar la inclusión de datos innecesarios para acelerar la descarga, ahorrar
ancho de banda y espacio de almacenamiento.
<p>En el momento de redactar este artículo, sólo Google Play utiliza el formato AAB. Las demás tiendas de aplicaciones no lo utilizan.
<h4>¿Por qué no usar IDE?</h4>
<p>Android Studio puede crear un AAB automáticamente con un solo clic. Hacerlo manualmente puede ser útil para entender mejor cómo funciona este proceso.
Por ejemplo, si está creando su propia herramienta para generar aplicaciones de Android, esta guía se puede utilizar como referencia.
Hay casos especiales en los que puede ser necesario evitar el uso de código generado automáticamente. Entonces, es posible que deba compilar el
paquete manualmente.
<p>&nbsp;
<h4>Las herramientas de trabajo</h4>
<p>Sólo necesitaremos el JDK, Android SDK y Bundletool. JDK es necesario para compilar el código Java y generar los binarios.
También se puede utilizar para generar el certificado para la firma. El SDK de Android contiene las herramientas necesarias para convertir el <i>bytecode</i>
al formato Dex usado por la máquina virtual Dalvik de Android, alinear y firmar el paquete. Bundletool se utiliza para generar el AAB.
También se usa para probar el AAB localmente, generando los APK específicos para cada dispositivo de prueba.
<p>Si aun no tiene JDK 1.6 o posterior instalado, lo puede descargar desde <a href="https://www.oracle.com/java/technologies/javase-downloads.html" target="_blank">el
sitio oficial de Oracle</a>. Asegúrese de instalar el Kit de Desarrollo Java (JDK), no solamente el entorno de ejecución JRE. Se recomienda configurar la
variable de entorno JAVA_HOME para que apunte a la ubicación de instalación de Java (sin incluir el subdirectorio bin). Esto no es obligatorio, pero ayuda
a evitar conflictos en la localización del JDK, especialmente si existen mas de una versión de JDK instaladas.
<p>La instalación del SDK de Android no es una tarea tan sencilla. Google ya no provee el paquete de instalación completo para el SDK. Existen 2 opciones alternas:
<p>&#x2022; Instalar Android Studio desde <a href="https://developer.android.com/studio" target="_blank">el sitio oficial</a>. Desde la página inicial del IDE se puede
realizar la instalación del SDK fácilmente.
<p>&#x2022; Otra opción consiste en descargar e instalar las herramientas de línea de comandos (<i>Command Line Tools</i>), las cuales están disponibles en la sección
más inferior de la <a href="https://developer.android.com/studio" target="_blank">misma página oficial</a>. Las herramientas de línea de comandos no son el SDK.
Luego de instalar estas herramientas de línea de comandos puede ejecutar el <a href="https://developer.android.com/studio/command-line/sdkmanager" target="_blank">sdkmanager</a>
para descargar y configurar el SDK de Android.
<p>Las herramientas <i>Build Tools</i> del SDK de Android deben tener al menos la versión 29.0.2. Es posible que las versiones anteriores no incluyan la
herramienta AAPT2 o que existan problemas de compatibilidad. También puede descargar la última versión de AAPT2 de Maven
<a href="https://developer.android.com/studio/command-line/aapt2" target="_blank">como se explica aquí</a>.
<p>La versión mas actual de Bundletool se puede <a href="https://github.com/google/bundletool/releases" target="_blank">descargar aquí</a>.
La herramienta es un único archivo JAR.
<p>&nbsp;
<h4>Ejemplo de proyecto</h4>
<p><a href="https://github.com/celersms/BatchAAB" target="_blank"><img src="https://www.celersms.com/static/github.png" alt="GitHub" align="left" hspace=10 border=0></a>Un ejemplo de proyecto completo,
incluyendo el código fuente Java y los archivos de procesamiento por lotes de Windows para crear y ejecutar el aplicativo Android, está disponible en <a href="https://github.com/celersms/BatchAAB"
target="_blank">nuestro repositorio de GitHub</a>.
<p>Se recomienda crear su propio certificado para firmar el APK. La herramienta <i>keytool</i> de JDK se puede usar para reemplazar nuestro certificado de ejemplo
con uno propio:
<pre style="background:#000;color:#fff">
del src\demo.keystore /q

REM El siguiente comando es una sola linea
"%JAVA_HOME%"\bin\keytool -genkey -keystore src\demo.keystore -keyalg RSA -keysize 2048 -validity 10000 -alias demo
</pre>
<p>La ruta <i>src\demo.keystore</i> se puede cambiar si desea almacenar el certificado en una ubicación distinta. Si no ha configurado la variable de entorno
JAVA_HOME, se debe especificar la ruta completa al ejecutar <i>keytool</i>. El tiempo de validez del certificado y el nombre del alias se pueden modificar.
<i>Keytool</i> requiere ingresar unos datos acerca de la organización, ubicación y solicitará asignar una contraseña. La contraseña de nuestro
<i>demo.keystore</i> es <i>password</i> (no es una clave realmente fuerte).
<p>&nbsp;
<h4>build.bat</h4>
<p>Antes de ejecutar <i>build.bat</i> se debe configurar los parámetros que se describen a continuación. Un editor de texto plano como el Bloc de Notas (<i>Notepad</i>)
se puede usar para editar <i>build.bat</i>:
<p>&#x2022; <b>BUILD_TOOLS</b> es la ubicación de las herramientas <i>Build Tools</i> dentro del SDK de Android. Utilice el valor de ejemplo como referencia.
<p>&#x2022; <b>ANDROID_JAR</b> es la ruta de <i>android.jar</i> para la versión de API requerida. Se recomienda utilizar la última versión de API disponible.
Esto no afecta la ejecución del APK en versiones de Android anteriores, a menos que la aplicación utilice características específicas de las nuevas versiones.
<p>&#x2022; <b>BUNDLETOOL</b> es la ubicación del archivo jar de Bundletool. Intente utilizar la última versión, si es posible.
<p>Revisemos las acciones que realiza el archivo de procesamiento por lotes paso a paso:
<p>1. Compilar los recursos. Este comando analiza los recursos (imágenes, xml, etc.) y los empaqueta en un archivo ZIP. Observe que para construir un AAB estamos usando la herramienta AAPT2 en lugar de AAPT.
<pre style="background:#000;color:#fff">
"%BUILD_TOOLS%\aapt2" compile --dir res\ -o obj\res.zip
</pre>
<p>2. Enlazar los recursos. Esta es una sola línea:
<pre style="background:#000;color:#fff">
"%BUILD_TOOLS%\aapt2" link --proto-format -o obj\linked.zip -I "%ANDROID_JAR%" --manifest src\AndroidManifest.xml --java src obj\res.zip --auto-add-overlay
</pre>
<p>3. Compilar el código fuente Java y generar el código binario (<i>bytecode</i>) correspondiente.
<pre style="background:#000;color:#fff">
"%JAVA_HOME%\bin\javac" -d obj -classpath src -bootclasspath "%ANDROID_JAR%" src\com\celer\hello\*.java
</pre>
<p>4. Convertir el <i>bytecode</i> al formato Dex utilizado por la máquina virtual Dalvik de Android.
<pre style="background:#000;color:#fff">
"%BUILD_TOOLS%\dx" --dex --output=bin\classes.dex obj
</pre>
<p>5. Combinar los recursos y el <i>bytecode</i> en un solo paquete:
<pre style="background:#000;color:#fff">
cd obj
"%JAVA_HOME%\bin\jar" xf linked.zip resources.pb AndroidManifest.xml res
mkdir manifest dex 2>nul
move AndroidManifest.xml manifest
copy /Y /B ..\bin\classes*.dex dex\ 2>nul
"%JAVA_HOME%\bin\jar" cMf base.zip manifest dex res resources.pb
</pre>
<p>6. Generar el AAB.
<pre style="background:#000;color:#fff">
"%JAVA_HOME%\bin\java" -jar "%BUNDLETOOL%" build-bundle --modules=base.zip --output=..\bin\hello.aab
</pre>
<p>7. Firmar el AAB.
<pre style="background:#000;color:#fff">
"%JAVA_HOME%\bin\jarsigner" -keystore ..\src\demo.keystore -storepass password ..\bin\hello.aab demo
</pre>
<p>Si no hay errores el resultado es un AAB listo para ser publicado en Google Play.
<p>&nbsp;
]]></description>
<dc:language>es</dc:language><dc:format>text/html</dc:format><dc:identifier>https://www.celersms.com/batch-aab-es.htm</dc:identifier>
</item>
<item>
	<title>¿Cómo cambiar un módem USB al modo de solo módem?</title>
	<pubDate>Sat, 26 Dec 2020 22:55:00 GMT</pubDate><author>admin@celersms.com (Vladimir Kame&#241;ar)</author>
	<link>https://www.celersms.com/modem-only-es.htm</link><guid isPermaLink="true">https://www.celersms.com/modem-only-es.htm</guid><description><![CDATA[
<p>Actualmente muchos módem USB emulan dispositivos de almacenamiento: unidad de CD flash o tarjeta micro SD. El <a href="https://es.wikipedia.org/wiki/Universal_Serial_Bus">bus USB</a> permite este tipo de emulación. Esto se convirtió en una práctica normal para muchos modelos de módem USB.
El dispositivo puede comportarse como una unidad flash (memoria extraíble) para permitir que el usuario instale los controladores y el software complementario.
<p><center><img src="https://www.celersms.com/images/modems.png" alt="Los módem USB"></center>
<p>No es necesario proporcionar un CD / DVD o descargar los controladores de Internet. Una vez instalados los controladores, el dispositivo se reconoce como módem o puerto COM virtual (VCP).
Esto es conveniente para el usuario común de Windows, pero complica las cosas en Linux. El módem aparecerá como unidad flash, no como un módem normal. Por lo tanto, no será posible enviar SMS.
El comando <i>media eject</i> (expulsión) puede hacer que el dispositivo USB active el modo de módem.
<p>Cuando el dispositivo recibe el comando de expulsión, puede desactivar la unidad de almacenamiento y habilitar la interfaz de módem. Es posible que este truco no funcione en algunos casos.
Las siguientes instrucciones proporcionan una forma genérica de reconfigurar el módem USB para que se comporte en modo "solo módem".
<p>&nbsp;
<h4>Modo de solo módem</h4>
<p style="background:#ebf5fb;border:1px dotted #06476e;padding:8px">
<b>¡Advertencia!</b> Estas instrucciones son para usuarios avanzados, desarrolladores, que necesitan interactuar con el módem directamente para enviar / recibir SMS o establecer una conexión a Internet.
No intente reconfigurar su módem si el propósito no es claro y necesario. En algunos casos, los cambios podrían ser irrevertibles.
<p>La opción más genérica y recomendada para Linux es utilizar el <a href="https://www.draisberghof.de/usb_modeswitch/">script USB_ModeSwitch</a>. Este script puede reconfigurar el dispositivo automáticamente.
<p>Para los módem Huawei y ZTE, existe un procedimiento alternativo que se puede ejecutar en Windows. Para realizar los pasos que se describen a continuación, deberá utilizar un software emulador de terminal como Hyper Terminal, PuTTY o nuestro <a href="https://www.celersms.com/CelerCOM-es.htm">CelerCOM TTY</a> gratuito.
<p>1. El primer paso es instalar el módem. El procedimiento exacto puede variar dependiendo del proveedor, pero suele ser sencillo. Simplemente conecte el dispositivo al puerto USB, espere el mensaje de ejecución automática
y siga las instrucciones en pantalla. Después de instalar el dispositivo, se recomienda realizar pruebas básicas, como conectarse a Internet, solo para asegurarse de que el dispositivo funcione correctamente
y la suscripción móvil esté activa.
<p>2. Identifique el puerto COM que está vinculado con el módem. Vaya a <b>Panel de control</b> &#8594; <b>Administrador de dispositivos</b>:
<p><center><img src="https://www.celersms.com/images/find-COM-Win-es.png" alt="Identifique el puerto COM" vspace=16></center>
<p>Siempre busque primero en la categoría <b>Módems</b>. Si no está allí, intente buscar en <b>Puertos (COM y LPT)</b>. A veces, el dispositivo puede aparecer repetido.
Ignore las ocurrencias con nombres como <i>debug</i> (depuración) o <i>diagnostics</i> (diagnóstico).
<p>3. En el ejemplo anterior, el puerto es COM26. Conéctese al puerto COM usando Hyper Terminal, PuTTY o CelerCOM TTY e ingrese el comando para habilitar el modo "solo módem".
Este comando es específico del proveedor. Por ejemplo, la mayoría de los módems ZTE admiten este comando: AT+ZCDRUN=8.
<p><center><img src="https://www.celersms.com/images/ZCDRUN8.png" alt="Cambiar ZTE al modo de solo módem: AT+ZCDRUN=8" vspace=16></center>
<p>&nbsp;
<h4>Comandos específicos del proveedor</h4>
<p>La siguiente tabla presenta los comandos específicos para habilitar el modo "solo módem" para algunos proveedores conocidos:
<table cellpadding=8 style="border:1px solid #ddd;margin-left:auto;margin-right:auto">
<tr style="border-bottom:1px solid #ddd"><th width=160>Proveedor<th width=160>Comando
<tr style="border-bottom:1px solid #ddd"><td>Huawei<td>AT^U2DIAG=0
<tr style="border-bottom:1px solid #ddd"><td>ZTE<td>AT+ZCDRUN=8 
<tr><td>ZTE (chipset Icera)<td>AT%USBMODEM=0
</table>
<p>&nbsp;
]]></description>
<dc:language>es</dc:language><dc:format>text/html</dc:format><dc:identifier>https://www.celersms.com/modem-only-es.htm</dc:identifier>
</item>
</channel>
</rss>