从未加密的领域迁移到加密的领域

时间:2018-11-29 13:17:13

标签: ios swift realm

我正在尝试从未加密的领域迁移到已加密的领域,但是我不知道如何使用Realm().writeCopy(toFile: url, encryptionKey: key)。 甚至还有另一种方法。

谢谢。

2 个答案:

答案 0 :(得分:1)

我找到了一种方法,您可以在下面找到它:

private static var realm: Realm! {

    // Get the encryptionKey
    var realmKey = Keychain.realmKey
    if realmKey == nil {
        var key = Data(count: 64)

        key.withUnsafeMutableBytes { (bytes) -> Void in
            _ = SecRandomCopyBytes(kSecRandomDefault, 64, bytes)
        }
        realmKey = key
        Keychain.realmKey = realmKey
    }


    // Check if the user has the unencrypted Realm
    let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
    let fileManager = FileManager.default
    let unencryptedRealmPath = "\(documentDirectory)/default.realm"
    let encryptedPath = "\(documentDirectory)/default_new.realm"
    let isUnencryptedRealmExsist = fileManager.fileExists(atPath: unencryptedRealmPath)
    let isEncryptedRealmExsist = fileManager.fileExists(atPath: encryptedPath)


    if isUnencryptedRealmExsist && !isEncryptedRealmExsist {
        let unencryptedRealm = try! Realm(configuration: Realm.Configuration(schemaVersion: 7))
        // if the user has unencrypted Realm write a copy to new path
        try? unencryptedRealm.writeCopy(toFile: URL(fileURLWithPath: encryptedPath), encryptionKey: realmKey)
    }

    // read from the new encrypted Realm path
    let configuration = Realm.Configuration(fileURL: URL(fileURLWithPath: encryptedPath), encryptionKey: realmKey, schemaVersion: 7, migrationBlock: { migration, oldSchemaVersion in })

    return try! Realm(configuration: configuration)
}

答案 1 :(得分:0)

根据@Abedalkareem Omreyh 的回答

您还可以检索应用的现有加密密钥(如果存在)或创建新密钥。

func getencryptionKey() -> 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)")
}

您可以将这个加密密钥用于上述代码,而无需检查密钥的 nil 值。

  // Get the encryptionKey
       var realmKey = getencryptionKey()

参考链接 Encrypt a Realm