¿Cómo puedo cifrar los contenidos de CoreData en un iPhone?

Tengo cierta información que me gustaría almacenar estáticamente cifrada en una aplicación de iPhone. Soy nuevo en el desarrollo de iPhone, algunos no estoy muy familiarizado con CoreData y cómo se integra con las vistas. Tengo los datos como JSON, aunque puedo ponerlos fácilmente en una base de datos SQLITE3 o cualquier otro formato de datos de respaldo. Tomaré lo que sea más fácil (a) cifrar y (b) para integrar con la capa de vista de iPhone.

El usuario deberá ingresar la contraseña para descifrar los datos cada vez que se inicie la aplicación. El objective del cifrado es evitar que los datos sean accesibles si el usuario pierde el teléfono.

Por razones de velocidad, preferiría cifrar y descifrar todo el archivo a la vez en lugar de cifrar cada campo individual en cada fila de la base de datos.

Nota: esta no es la misma idea que la Pregunta 929744 , cuyo propósito es evitar que el usuario se meta con los datos o los vea. Los datos deben ser perfectamente transparentes cuando estén en uso.

También tenga en cuenta: estoy dispuesto a usar SQLCipher para almacenar los datos, pero preferiría usar cosas que ya existen en el marco de iPhone / CoreData en lugar de pasar por el largo proceso de comstackción / integración involucrado.

Puede encriptar propiedades individuales en sus entidades de modelo de Datos centrales convirtiéndolas en propiedades transformables y luego creando una subclase NSValueTransformer que cifrará y descifrará los datos de esa propiedad. Si bien este no es el descifrado de la base de datos completa que está buscando, tendrá una huella de memoria mucho menor que descifrar una base de datos completa en la memoria. Además, permitirá que el descifrado se realice de forma perezosa, en lugar de todo desde el principio, por lo que su aplicación se cargará mucho más rápido. Dependiendo del cifrado utilizado, incluso esperaría que los accesos de datos en disco para cargar cada entidad sean más lentos que el proceso de descifrado de las propiedades, por lo que no verá una gran penalización de rendimiento al acceder a las propiedades.

Las propiedades transformables como esta son muy fáciles de usar, ya que las lee y las escribe de forma normal, mientras que el cifrado / descifrado continúa detrás de las escenas.

¿Necesitas encriptar? Los iPhones más nuevos (3Gs, 4, iPad …) encriptan todos los datos en el dispositivo. Con una contraseña única, hash, salada en su aplicación, nadie puede acceder a los datos sin una contraseña. Los datos están en la zona de pruebas de todas las demás aplicaciones.

Protección de datos en iOS

Logré adaptar el código de ejemplo CustomAtomicStoreSubclass de Apple para su uso en una aplicación de escritorio Mac, lo que resultó en una tienda persistente estilo NSBinaryStore cifrada escrita como un único archivo en el sistema de archivos. Mi acercamiento:

  • Copie el código fuente de la clase CustomAtomicStoreSubclass & CustomAtomicStoreSubclassCacheNode en mi proyecto y CustomAtomicStoreSubclassCacheNode nombre
  • Almacene la llave y el vector inicial en el llavero
  • Utilice la biblioteca OpenSSL incluida con Mac OS X
  • Cifre la salida NSKeyedArchiver y escriba el texto cifrado en el disco (el descifrado es el inverso)

Intercepté las lecturas y escrituras de la tienda de respaldo en los readFile , metadataForPersistentStoreWithURL:error: setMetadata:forPersistentStoreWithURL:error: y save: en CustomAtomicStoreSubclass .

Las notas de subclases para la referencia de clase NSAtomicStore del iPhone son similares a las de Mac OS X. Tal vez este enfoque también podría funcionar con el iPhone.

Sé que esta es una pregunta antigua, pero sigue siendo bastante relevante y recientemente tuve que abordar el tema yo mismo.

Las propiedades transformables son una solución potencial, pero no parecen funcionar con NSPredicates, lo que es un gran inconveniente. No seguí el enfoque CustomAtomicStoreSubclass, pero tengo curiosidad por saber si otros han tenido éxito.

Mis preocupaciones eran similares a las del cartel original, y al final terminé haciendo lo siguiente:

  1. Descifrar la tienda en un archivo temporal
  2. Cargue la tienda descifrada normalmente
  3. Migre la tienda a una tienda en memoria
  4. Eliminar la tienda no cifrada

En mi caso, mi tienda era de solo lectura, pero podría expandirse para volver a escribir la tienda, encriptarla y eliminar la tienda no encriptada una vez más. También puede omitir el n. ° 3 si tiene una tienda grande y / o no está preocupado por tener un archivo sin encriptar mientras su aplicación se está ejecutando.

El archivo Core Data con el que estaba trabajando tenía ~ 1MB, y podría encriptarse / descifrarse muy rápidamente.

Actualmente estoy usando https://github.com/project-imas/encrypted-core-data para cifrar mi tienda coredata. Es una implementación personalizada de NSIncrementalStore básicamente es un reemplazo de la comunidad para la propia tienda persistente de apple que tiene una opción de encriptación. Es una solución de inserción que funciona. También puede sacar el archivo sqlite y descifrarlo con el código que elija en muchos clientes diferentes.

La implementación no tiene una cobertura del 100% y no permite algunas características como los predicados de subconsulta. Tengo que enviar mi primer RP al repository para esperar que cambie pronto ;-). Casi lo tengo trabajando completamente con una aplicación de coredatos muy compleja . También tiene la ventaja adicional de permitirle dirigir el acceso de SQLite sin tener que preocuparse de que la implementación de Apple cambie en usted ya que tiene acceso completo a la fuente.

“El objective del cifrado es evitar que los datos sean accesibles si el usuario pierde el teléfono”.

iOS tiene Data Protection desde iOS 4, y Core Data lo ha soportado durante mucho tiempo. La protección de datos está diseñada para exactamente los tipos de escenarios en los que está interesado. De manera predeterminada, los archivos Core Data NSSQLiteStoreType tienen NSFileProtectionCompleteUntilFirstUserAuthentication para las aplicaciones creadas con la API iOS 5 o posterior. La sesión de WWDC 2012 Protecting the User’s Data NSFileProtectionComplete este tema con mucho más detalle y recomienda utilizar NSFileProtectionComplete . Puede usar esto con Core Data pasando ese valor en el diccionario de opciones utilizado para abrir su tienda Core Data NSSQLiteStoreType .

Ejemplo:

 NSDictionary *storeOptions = @{ NSPersistentStoreFileProtectionKey : NSFileProtectionComplete }; if (![coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self storeURL] options:storeOptions error:&error]){ 

El tema más amplio de la seguridad del dispositivo está cubierto en iOS Device Security

¿Cómo encripto o descifro los datos?

“La API de certificados, claves y servicios de confianza proporciona funciones para generar claves de cifrado simétricas y asimétricas, crear y verificar firmas digitales y cifrar claves y nonces. La biblioteca CommonCrypto se utiliza para cifrado simétrico, hashing y operaciones HMAC. , Clave y referencia de servicios de confianza y las páginas man de CC_crypto (3cc) para más información. ”

Puedes usar Transformables, y confirmo, no puedes usarlos con predicados, pero (y es peor) ni siquiera puedes usar

… = [self primitiveValueForKey: @ “crypted_data”];

si usa predicados …

funciona bien si criptas tus datos usando:

 [self setPrimitiveValue:cryptedPsw forKey:@"crypted_data"]; 

para criptar datos. (y, por ejemplo, en el simulador … y avance en el paquete del proyecto más adelante …)

El cifrado es un cifrado sin importar en qué formato se encuentren sus datos, y ciertamente no necesita preocuparse por cómo algo “se integra con las vistas”. Todo lo que tienes que hacer es descifrarlo antes de intentar leer algo significativo.