Docs Menu
Docs Home
/ /
Archivos del reino

Cifrar un dominio - Swift SDK

Puedes cifrar el archivo Realm en el disco con AES-256 + SHA-2 proporcionando una llave de cifrado de 64 bytes al abrir un realm.

Realm cifra y descifra datos de forma transparente con estándares Cifrado AES-256Utilizando los primeros 256 bits de la clave de cifrado de bits 512dada. Realm utiliza los otros 256 bits de la 512clave de cifrado de bits para validar la integridad mediante un código de autenticación de mensajes basado en hash (HMAC).

Advertencia

No utilice hashes criptográficamente débiles para las claves de cifrado de dominio. Para una seguridad óptima, recomendamos generar claves de cifrado aleatorias en lugar de derivadas.

Nota

No se puede cifrar un dominio existente sin cifrar

Debes cifrar un dominio la primera vez que lo abras. Si intentas abrir un dominio existente sin cifrar con una configuración que contiene una clave de cifrado, Realm generará un error.

Los siguientes son los impactos clave a tener en cuenta al cifrar un reino.

Debes pasar la misma clave de cifrado cada vez que abras el dominio cifrado. Si no proporcionas una clave o especificas una incorrecta para un dominio cifrado, el SDK de Realm generará un error.

Las aplicaciones deben almacenar la clave de cifrado en el llavero para que otras aplicaciones no puedan leerla.

Las lecturas y escrituras en reinos cifrados pueden ser hasta un 10% más lentas que en reinos no cifrados.

Puede encriptar un realm sincronizado.

Realm solo cifra los datos del dispositivo y los almacena sin cifrar en la fuente de datos Atlas. Cualquier usuario con acceso autorizado a la fuente de datos Atlas puede leerlos, pero se aplica lo siguiente:

  • Los usuarios deben tener los permisos de lectura correctos para leer los datos sincronizados.

  • Los datos almacenados en Atlas siempre están cifrados a nivel de volumen (disco).

  • La transferencia entre el cliente y el servidor siempre está totalmente cifrada.

También puede habilitar la Administración de claves del cliente para cifrar los datos de Atlas almacenados utilizando la clave de su proveedor de nube (por ejemplo, AWS KMS, Azure Key Vault, Google Cloud KMS).

Si necesita claves únicas para cada usuario de su aplicación, puede utilizar un proveedor OAuth o utilizar uno de los proveedores de autenticación de Realm y un activador de autenticación para crear 64una clave de bits y almacenar esa clave en un objeto de usuario.

Cambiado en la versión 10.38.0.

A partir de la versión 10.38.0 del SDK de Realm Swift, Realm admite la apertura del mismo reino cifrado en múltiples procesos.

Si su aplicación usa la versión 10.37.2 o anterior del SDK de Realm Swift, al intentar abrir un reino cifrado desde varios procesos se genera este error: Encrypted interprocess sharing is currently unsupported.

Las aplicaciones que utilizan versiones anteriores del SDK tienen dos opciones para trabajar con dominios en múltiples procesos:

  • Utilice un reino no cifrado.

  • Almacene los datos que desee cifrar como propiedades NSData en objetos de dominio. Después, podrá cifrar y descifrar campos individuales.

Una herramienta posible para cifrar y descifrar campos es el framework CryptoKit de Apple. Puedes usar Swift Crypto para simplificar el desarrollo de aplicaciones con CryptoKit.

El siguiente código demuestra cómo generar una clave de cifrado y abrir un reino cifrado:

// Generate a random encryption key
NSMutableData *key = [NSMutableData dataWithLength:64];
(void)SecRandomCopyBytes(kSecRandomDefault, key.length, (uint8_t *)key.mutableBytes);
// Open the encrypted Realm file
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
config.encryptionKey = key;
NSError *error = nil;
RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:&error];
if (!realm) {
// If the encryption key is wrong, `error` will say that it's an invalid database
NSLog(@"Error opening realm: %@", error);
} else {
// Use the realm as normal...
}
// Generate a random encryption key
var key = Data(count: 64)
_ = key.withUnsafeMutableBytes { (pointer: UnsafeMutableRawBufferPointer) in
SecRandomCopyBytes(kSecRandomDefault, 64, pointer.baseAddress!) }
// Configure for an encrypted realm
var config = Realm.Configuration(encryptionKey: key)
do {
// Open the encrypted realm
let realm = try Realm(configuration: config)
// ... use the realm as normal ...
} catch let error as NSError {
// If the encryption key is wrong, `error` will say that it's an invalid database
fatalError("Error opening realm: \(error.localizedDescription)")
}

El siguiente ejemplo de Swift demuestra cómo almacenar y recuperar una clave generada desde el llavero:

// Retrieve the existing encryption key for the app if it exists or create a new one
func getKey() -> Data {
// Identifier for our keychain entry - should be unique for your application
let keychainIdentifier = "io.Realm.EncryptionExampleKey"
let keychainIdentifierData = keychainIdentifier.data(using: String.Encoding.utf8, allowLossyConversion: false)!
// First check in the keychain for an existing key
var query: [NSString: AnyObject] = [
kSecClass: kSecClassKey,
kSecAttrApplicationTag: keychainIdentifierData as AnyObject,
kSecAttrKeySizeInBits: 512 as AnyObject,
kSecReturnData: true as AnyObject
]
// To avoid Swift optimization bug, should use withUnsafeMutablePointer() function to retrieve the keychain item
// See also: http://stackoverflow.com/questions/24145838/querying-ios-keychain-using-swift/27721328#27721328
var dataTypeRef: AnyObject?
var status = withUnsafeMutablePointer(to: &dataTypeRef) { SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0)) }
if status == errSecSuccess {
// swiftlint:disable:next force_cast
return dataTypeRef as! Data
}
// No pre-existing key from this application, so generate a new one
// Generate a random encryption key
var key = Data(count: 64)
key.withUnsafeMutableBytes({ (pointer: UnsafeMutableRawBufferPointer) in
let result = SecRandomCopyBytes(kSecRandomDefault, 64, pointer.baseAddress!)
assert(result == 0, "Failed to get random bytes")
})
// Store the key in the keychain
query = [
kSecClass: kSecClassKey,
kSecAttrApplicationTag: keychainIdentifierData as AnyObject,
kSecAttrKeySizeInBits: 512 as AnyObject,
kSecValueData: key as AnyObject
]
status = SecItemAdd(query as CFDictionary, nil)
assert(status == errSecSuccess, "Failed to insert the new key in the keychain")
return key
}
// ...
// Use the getKey() function to get the stored encryption key or create a new one
var config = Realm.Configuration(encryptionKey: getKey())
do {
// Open the realm with the configuration
let realm = try Realm(configuration: config)
// Use the realm as normal
} catch let error as NSError {
// If the encryption key is wrong, `error` will say that it's an invalid database
fatalError("Error opening realm: \(error)")
}

Volver

Reducir el tamaño del archivo de Realm

En esta página