SWIFT - Realm db encryption not working

泪湿孤枕 提交于 2019-11-30 20:51:35

问题


Im trying to encrypt the data stored in the realm database. I followed the Sample Code mentioned on Realm's Swift page. I want to encrypt the data NOT the database file. Below is the code I'm using:

    var error: NSError? = nil
    let configuration = Realm.Configuration(encryptionKey: EncryptionManager().getKey())

    if let realmE = Realm(configuration: configuration, error: &error) {
        // Add an object
        realmE.write {
            realmE.add(objects, update: T.primaryKey() != nil)
        }
    }

Where objects is a list of objects i need to insert in the database. Below is the code fore getKey() func also picked from the sample code:

func getKey() -> NSData {
    // Identifier for our keychain entry - should be unique for your application
    let keychainIdentifier = "io.Realm.test"
    let keychainIdentifierData = keychainIdentifier.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!

    // First check in the keychain for an existing key
    var query: [NSString: AnyObject] = [
        kSecClass: kSecClassKey,
        kSecAttrApplicationTag: keychainIdentifierData,
        kSecAttrKeySizeInBits: 512,
        kSecReturnData: true
    ]

    // 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(&dataTypeRef) { SecItemCopyMatching(query, 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, UnsafeMutablePointer<UInt8>(keyData.mutableBytes))

    // Store the key in the keychain
    query = [
        kSecClass: kSecClassKey,
        kSecAttrApplicationTag: keychainIdentifierData,
        kSecAttrKeySizeInBits: 512,
        kSecValueData: keyData
    ]

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

    return keyData
}

The problem is this that the code is not getting encrypted. After inserting data when i open the realm file using Realm Browser the code is NOT encrypted.

Tested on both simulator and device. Using Swift 1.2, Xcode 6.4, Realm 0.95.

Any ideas?


回答1:


Realm's encryption feature applies only to the ability to encrypt whole .realm files. There's no feature to encrypt discrete objects within the .realm file and leave the rest as-is.

If you do want to go about doing this, I'm afraid you would need to roll the encryption system yourself.

If I was going to do this, I'd do it this way:

  1. Create a Realm Object subclass with an NSData property called encryptedData.
  2. Serialize any objects you wanted to encrypt to NSData using the NSCoding protocol. (Saving custom SWIFT class with NSCoding to UserDefaults)
  3. Encrypt that resulting NSData object using an encryption method of your choice (AES Encryption for an NSString on the iPhone)
  4. Take the resulting encrypted NSData object and save it to the encryptedData property in your Realm object.
  5. Reverse the process when you want to retrieve that data.

While this process would work, as you can see, it's a non-trivial amount of extra work, and you would also lose all of the speed and memory-saving benefits of Realm in the process.

I would encourage you to rethink your app's design, and see if it is feasible to use Realm's own encryption feature after all. Good luck!



来源:https://stackoverflow.com/questions/32718005/swift-realm-db-encryption-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!