para - ¿Cómo mantendría los datos secretos en secreto en una aplicación de iPhone?
limpiar memoria iphone (10)
Digamos que necesito acceder a un servicio web desde una aplicación de iPhone. Este servicio web requiere que los clientes firmen digitalmente solicitudes HTTP para demostrar que la aplicación "conoce" un secreto compartido; una clave de cliente. La firma de la solicitud se almacena en un encabezado HTTP y la solicitud simplemente se envía a través de HTTP (no HTTPS).
Esta clave debe mantenerse en secreto en todo momento, pero debe ser utilizada por la aplicación de iPhone.
Entonces, ¿cómo almacenaría esta clave de forma segura dado que siempre le han dicho que nunca almacene nada confidencial en el lado del cliente?
El usuario promedio (99% de los usuarios) simplemente usará la aplicación. Habrá alguien (¿un enemigo?) Que quiera esa clave de cliente secreta para hacer daño al servicio o al propietario de la clave del cliente por medio de la suplantación. Tal persona podría hacer jailbreak a su teléfono, obtener acceso al binario, ejecutar ''cadenas'' o un editor hexadecimal y explorar. Por lo tanto, solo almacenar la clave en el código fuente es una idea terrible.
Otra idea es almacenar la clave en código, no un literal de cadena, sino en un archivo NSMutableArray creado a partir de literales de bytes.
Uno puede usar el llavero pero como una aplicación de iPhone nunca tiene que proporcionar una contraseña para almacenar cosas en el llavero, me preocupa que alguien con acceso al recinto de seguridad de la aplicación pueda y pueda simplemente mirar o trivialmente decodificar elementos allí.
EDITAR - así que leí esto sobre el llavero: "En iPhone OS, una aplicación siempre tiene acceso a sus propios elementos de llavero y no tiene acceso a ningún otro elemento de la aplicación. El sistema genera su propia contraseña para el llavero y almacena la llave en el dispositivo de tal manera que no sea accesible para ninguna aplicación ".
Entonces, tal vez este sea el mejor lugar para almacenar la llave ... En caso afirmativo, ¿cómo realizo el envío con la llave introducida previamente en el llavero de la aplicación? ¿Es eso posible? De lo contrario, ¿cómo podría agregar la clave en el primer lanzamiento sin que la clave esté en el código fuente? Hmm ...
EDITAR - Informe de error presentado # 6584858 en http://bugreport.apple.com
Gracias.
¿Consideró / intentó la sugerencia de Push Notification, para transmitir inicialmente el secreto de la aplicación y el llavero? ¿O terminas encontrando algún otro método para lograr esto?
Creo que esta pregunta similar y mi answer, pueden ser relevantes para su caso. En pocas palabras, se habló de la presencia de un módulo de plataforma confiable en un iPhone. Esto permitiría que su servicio confíe en un iPhone, incluso en manos de un atacante. Sin embargo, parece que usar el llavero es tu mejor opción.
El objetivo es, en última instancia, restringir el acceso del servicio web a los usuarios autorizados, ¿verdad? Muy fácil si controlas el servicio web (si no lo haces, envuélvelo en un servicio web que controlas).
1) Crea un par de claves públicas / privadas. La clave privada va al servidor del servicio web, que se coloca en un calabozo y es custodiado por un dragón. La clave pública va por teléfono. Si alguien puede leer la clave pública, esto no es un problema .
2) Haga que cada copia de la aplicación genere un identificador único. Cómo lo haces depende de ti. Por ejemplo, podría compilarlo en el ejecutable en la descarga (¿es esto posible para las aplicaciones de iPhone)? Podría usar el GUID del teléfono, suponiendo que tengan una forma de calcular uno. También podría rehacer esto por sesión si realmente quisiera.
3) Use la clave pública para encriptar "Mi identificador único es $ FOO y he aprobado este mensaje". Envíelo con cada solicitud al servicio web.
4) El servicio web descifra cada solicitud, rebotando cualquiera que no contenga un identificador válido. Puede hacer tanto o tan poco trabajo como desee aquí: mantener una lista blanca / lista negra, controlar el uso por identificador e investigar el comportamiento sospechoso, etc.
5) Debido a que el identificador único ahora nunca se envía por cable, la única forma de comprometerlo es tener acceso físico al teléfono. Si tienen acceso físico al teléfono, perderás el control de cualquier dato en cualquier parte del teléfono . Siempre. No puede ser ayudado Es por eso que construimos el sistema de tal manera que poner en peligro un teléfono nunca compromete más de una cuenta.
6) Desarrollar procesos de negocio para acomodar la necesidad de a) eliminar el acceso de un usuario que está abusando de él yb) restaurar el acceso a un usuario cuyo teléfono ha sido físicamente comprometido (esto será muy, muy poco frecuente a menos que el usuario sea el adversario).
La respuesta simple es que, tal como están las cosas hoy en día, no es posible guardar secretos en el iPhone. Un iPhone con jailbreak es solo una computadora de propósito general que cabe en tu mano. No hay un hardware de plataforma de confianza al que pueda acceder. El usuario puede falsificar cualquier cosa que pueda imaginar utilizando para identificar de forma única un dispositivo determinado. El usuario puede inyectar código en su proceso para hacer cosas como inspeccionar el llavero. (Busque MobileSubstrate para ver a qué me refiero.) Lo siento, está jodido.
Un rayo de luz en esta situación se encuentra en los recibos de compra de la aplicación. Si vende un artículo en su aplicación mediante la compra en la aplicación, obtiene un recibo que está firmado con cifrado y se puede verificar con Apple a pedido. A pesar de que no puede mantener el recibo en secreto, puede rastrearse (por Apple, no por usted) a una compra específica, lo que puede desalentar a los piratas de compartirlos. También puede acelerar el acceso a su servidor por recibo para evitar que los piratas consuman los recursos de su servidor.
Si puede soportar ser iPhone OS 3.0-only, es posible que desee consultar las notificaciones push. No puedo entrar en detalles, pero puede entregar una carga a los servidores de Apple junto con la notificación en sí. Cuando aceptan la alerta (o si su aplicación se está ejecutando), se llama a una parte de su código y se almacena el ítem llavero. En este punto, esa es la única ruta para almacenar de forma segura un secreto en un iPhone que puedo pensar.
Suena wonky. Usaría HTTPS y tal vez un paquete de cifrado para manejar la clave.
Creo que CommonCrypto está disponible para iPhone.
EDITAR: Todavía suena inestable. ¿Por qué alguien pasaría una clave secreta en un encabezado HTTP? Cualquiera que rastree su tráfico de red (a través de un enrutador wifi de inicio de sesión, por ejemplo) lo vería.
Existen métodos de seguridad bien establecidos para cifrar el tráfico de mensajes ... ¿por qué no usarlos en lugar de inventar lo que básicamente es un sistema trivialmente defectuoso?
EDIT II: Ah, ya veo. Me gustaría seguir adelante y usar el llavero ... Creo que es solo para este tipo de casos. Eché de menos que estabas generando la solicitud usando la clave. Todavía podría usar HTTPS si pudiera, ya que de esa manera no se arriesga a que la gente deduzca su esquema de generación de claves mediante la inspección de suficientes firmas.
Tenía la misma pregunta y pasé mucho tiempo hurgando por una respuesta. El problema es el huevo y la gallina: cómo preconocer el llavero con los datos que necesita tu aplicación.
En cualquier caso, encontré una técnica que al menos dificultará que un jailbreaker descubra la información: al menos tendrán que desmontar el código para descubrir qué hizo para enmascarar la información:
Ofuscación de cadenas (si el enlace rompe la búsqueda de "Obfuscar / Encriptar una cadena (NSString)")
Esencialmente, la cadena está ofuscada antes de colocarla en la aplicación, luego la desenmascaras usando código.
Es mejor que no hacer nada.
David
EDITAR: De hecho, lo usé en una aplicación. Puse una cadena de codificación base en el info.plist, luego hice varias operaciones en el código - rot13, rotar / invertir bytes, etc. La cadena procesada final se utilizó para decodificar la cadena ofuscada. Ahora, las agencias de tres letras podrían romper esto, pero a un gran costo de muchas horas decodificando el binario.
Iba a decir que esta es la mejor técnica que he encontrado, pero acabo de leer la publicación de Kiran en UAObfuscatedString (respuesta diferente), que es una forma completamente diferente de ofuscar. Tiene la ventaja de que no hay cadenas guardadas en ninguna parte de la aplicación: cada letra se convierte en una llamada a método. Los selectores se mostrarán como cadenas, por lo que un hacker puede decir rápidamente que su clase usó esa técnica.
Voy a hacer que mi aplicación de iPhone cargue imágenes en Amazon S3. En lugar de poner las credenciales de AWS en la aplicación, voy a tener el teléfono de la aplicación en mi servidor para que el URI y los encabezados se usen en la solicitud de carga de S3. Mi servidor generará URI S3, firmas adecuadas, etc. Luego puedo implementar un modelo de seguridad más estricto y específico en el servicio web de mi aplicación que AWS ofrece por sí mismo y no entregar mis llaves AWS a nadie con un iPhone con jailbreak.
Pero todavía debe haber cierta confianza (credenciales u otras) otorgada a la aplicación, y esa confianza puede ser robada. Todo lo que puedes hacer es limitar el daño que se produce si alguien bloquea un iPhone y roba las credenciales de la aplicación. Mientras más poderosas sean esas credenciales, las peores cosas son. Las formas de limitar el poder de las credenciales incluyen:
- evitar credenciales globales hacerlos por usuario / aplicación
- evitar credenciales permanentes. hacerlos temporales si es posible
- evitar los permisos globales. darles solo los permisos que necesitan. por ejemplo, los permisos de escritura podrían desglosarse en insertar, sobrescribir, eliminar, escribir en el grupo de recursos A o B, etc., y leer podría dividirse en leer recursos nombrados, leer una lista de todos los recursos existentes, leer grupos de recursos A o B , etc.
Yo recomendaría crear una clave en tiempo de ejecución si es posible. De esta forma, si la clave fuera aprehendida durante una sesión en particular, una vez que la sesión finalice, la clave no tendrá valor. Todavía podrían aprehender la clave de la memoria si son lo suficientemente inteligentes, pero no importaría ya que la clave se volvería inválida después de un período de tiempo.
UAObfuscatedString podría ser una solución a su problema. De los documentos:
Cuando escribe código que tiene una constante de cadena, esta cadena se guarda en el binario en texto claro. Un hacker podría descubrir exploits o cambiar la cadena para afectar el comportamiento de su aplicación. UAObfuscatedString solo almacena caracteres individuales en el binario, luego los combina en tiempo de ejecución para producir su cadena. Es muy poco probable que estas letras individuales sean detectables en el binario, ya que se interpondrán en lugares aleatorios en el código compilado. Por lo tanto, parecen ser código aleatorio para cualquiera que intente extraer cadenas.