如何在现有领域数据库上应用加密

时间:2015-07-03 10:44:45

标签: encryption realm

我有一个使用非加密领域数据库的iOS应用程序。

现在我想在该数据库上应用加密

我可以使用以下方式设置加密密钥

Realm.setEncryptionKey(key, forPath: Realm.defaultPath)

然后领域将加密现有数据库?

或者我是否需要使用加密创建域数据库文件,然后现有数据库中的数据移动到新加密数据库?

2 个答案:

答案 0 :(得分:8)

您必须创建未加密的Realm文件的加密副本,您可以使用Realm().writeCopyToPath(_:encryptionKey:)执行此操作,然后您可以在新位置使用加密文件。< / p>

答案 1 :(得分:0)

你必须做类似下面的事情

  1. 生成返回值 func encryptedrealm() -> Realm 的函数

    func encryptedrealm() {

    // Get the encryptionKey
    var realmKey = getencryptionKey()
    

    // 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. 创建加密密钥或从钥匙串中获取存在的密钥,使函数`func getencryptionKey() -> 数据

func getencryptionKey() {

let keychainIdentifier = "io.Realm.EncryptionKey"

    let keychainIdentifierData = keychainIdentifier.data(using: String.Encoding.utf8, allowLossyConversion: false)!
   
    var query: [NSString: AnyObject] = [
        kSecClass: kSecClassKey,
        kSecAttrApplicationTag: keychainIdentifierData as AnyObject,
        kSecAttrKeySizeInBits: 512 as AnyObject,
        kSecReturnData: true as AnyObject
    ]
  
    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")
    })
   
    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


 }
  1. 现在你可以像下面这样使用领域

    let realm = encryptedrealm()