【问题标题】:Migrate from unencrypted realm to encrypted realm从未加密领域迁移到加密领域
【发布时间】:2018-11-29 13:17:13
【问题描述】:

我正在尝试从未加密领域迁移到加密领域,但我不知道如何以及在何处使用 Realm().writeCopy(toFile: url, encryptionKey: key)。 或者即使有其他方法。

谢谢。

【问题讨论】:

    标签: ios swift realm


    【解决方案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)
    }
    

    【讨论】:

      【解决方案2】:

      根据@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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-04
        • 1970-01-01
        • 2019-08-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-03
        • 1970-01-01
        相关资源
        最近更新 更多