realm / realm-swift

Realm is a mobile database: a replacement for Core Data & SQLite
https://realm.io
Apache License 2.0
16.27k stars 2.14k forks source link

Realm file decryption failed Path #6199

Closed eitanaviv closed 4 years ago

eitanaviv commented 5 years ago

Goals

I want an encrypted Realm file to be used in my iOS app.

Expected Results

Have a working Realm based app to be working. It is working, but i'm getting many crash reports.

Actual Results

Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=io.realm Code=2 "Unable to open a realm at path '/var/mobile/Containers/Data/Application/6D5367BE-6E60-49C2-A8DB-367AE9B2D723/Documents/myRealm.realm': Realm file decryption failed Path:." UserInfo={Error Code=2, NSFilePath=/var/mobile/Containers/Data/Application/6D5367BE-6E60-49C2-A8DB-367AE9B2D723/Documents/myRealm.realm, Underlying=Realm file decryption failed Path: /var/mobile/Containers/Data/Application/6D5367BE-6E60-49C2-A8DB-367AE9B2D723/Documents/myRealm.realm, NSLocalizedDescription=Unable to open a realm at path '/var/mobile/Containers/Data/Application/6D5367BE-6E60-49C2-A8DB-367AE9B2D723/Documents/myRealm.realm': Realm file decryption failed Path:.}: file /Users/eitanimac/Desktop/ios_apps/EitanApp/EitanApp/AppDelegate.swift, line 93

Steps to Reproduce

I have no idea as i cannot manage to reproduce it myself and none of my co-workers with iOS seem to experience any bugs with the app.

Code Sample

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        GMSServices.provideAPIKey(“XXX”)
        GMSPlacesClient.provideAPIKey(“XXX”)
        FirebaseApp.configure()

        Fabric.with([Crashlytics.self])

        // Delete the old default realm file if exists and replace it with new encrypted one
        if FileManager.default.fileExists(atPath: Realm.Configuration().fileURL!.path) {
            do {
                try FileManager.default.removeItem(at: Realm.Configuration().fileURL!)
            } catch {
                print("Removing error")
            }
        }

        var encryptionKey: Data? = nil

        #if DEBUG
        encryptionKey = nil
        #else
        encryptionKey = getKey() as Data
        #endif

        print("Realm file path: \(Realm.Configuration.defaultConfiguration.fileURL?.absoluteString ?? "")")

        Realm.Configuration.defaultConfiguration = Realm.Configuration(fileURL: Realm.Configuration().fileURL!.deletingLastPathComponent().appendingPathComponent("myRealm.realm"),
                                                                       encryptionKey: encryptionKey,
                                                                       schemaVersion: 1,
                                                                       migrationBlock: { migration, oldSchemaVersion in
        })

        print("Realm file path: \(Realm.Configuration().fileURL?.absoluteString ?? "")")

        let realm = try! Realm()

        //Check which StoryBoard to init
        var storyboardName: String = ""
        let user = realm.objects(User.self).first

        if let user = user {
            storyboardName = "Main"
        } else {
            storyboardName = "Welcome"
        }

        let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
        let intialVC = storyboard.instantiateInitialViewController()
        self.window?.rootViewController = intialVC
        self.window?.makeKeyAndVisible()

        UIApplication.shared.registerForRemoteNotifications()

        return true
    }

    func getKey() -> NSData {
        // Identifier for our keychain entry - should be unique for your application
        let keychainIdentifier = “eitan.com.MyApp”
        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 {
            return dataTypeRef as! NSData
        }

        // No pre-existing key from this application, so generate a new one
        let keyData = NSMutableData(length: 64)!
        let result = SecRandomCopyBytes(kSecRandomDefault, 64, keyData.mutableBytes.bindMemory(to: UInt8.self, capacity: 64))
        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: keyData
        ]

        status = SecItemAdd(query as CFDictionary, nil)
        assert(status == errSecSuccess, "Failed to insert the new key in the keychain")

        return keyData
    }
}

Version of Realm and Tooling

ProductName:    Mac OS X
ProductVersion: 10.14.5
BuildVersion:   18F132

/Applications/Xcode.app/Contents/Developer
Xcode 10.2.1
Build version 10E1001

/usr/local/bin/pod
1.7.0.beta.1
Realm (3.17.0)
RealmSwift (3.17.0)

/bin/bash
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)

(not in use here)

/usr/bin/git
git version 2.20.1 (Apple Git-117)

As i said, the crash happen in many devices that i can see in Fabric, but none of my co-workers can seem to experience any crashes from the app.

The code sample i've put is combined from many solutions i found in the internet.

Looking forward to get some help and solve this already! Thanks!

jsflax commented 4 years ago

@eitanaviv Is this still an issue? Can you update your version of Realm? The version you are using is fairly out of date.

jsflax commented 4 years ago

Going to close this out as it's been a couple of months and a number of releases have occurred. If this is still an issue, please open a new ticket.