diff --git a/README.md b/README.md index 3fecfce..c02453f 100644 --- a/README.md +++ b/README.md @@ -163,13 +163,14 @@ You can customize the identifiers used for the master key in the Keychain: ```swift let config = EncryptionConfiguration( masterKeyService: "com.myapp.LocalData", - masterKeyAccount: "MasterKey" + masterKeyAccount: "MasterKey", + pbkdf2Iterations: 50_000 ) await StorageRouter.shared.updateEncryptionConfiguration(config) ``` > [!WARNING] -> Changing the `masterKeyService` or `masterKeyAccount` in an existing app will cause the app to look for the master key in a new location. Previously encrypted data will be lost. +> Changing the `masterKeyService`, `masterKeyAccount`, or `pbkdf2Iterations` in an existing app will cause the app to look for or derive keys differently. Previously encrypted data will be inaccessible. #### Global Sync Configuration diff --git a/Sources/LocalData/Configuration/EncryptionConfiguration.swift b/Sources/LocalData/Configuration/EncryptionConfiguration.swift index c272806..851340a 100644 --- a/Sources/LocalData/Configuration/EncryptionConfiguration.swift +++ b/Sources/LocalData/Configuration/EncryptionConfiguration.swift @@ -6,17 +6,20 @@ public struct EncryptionConfiguration: Sendable { public let masterKeyAccount: String public let masterKeyLength: Int public let defaultHKDFInfo: String + public let pbkdf2Iterations: Int public init( masterKeyService: String = "LocalData", masterKeyAccount: String = "MasterKey", masterKeyLength: Int = 32, - defaultHKDFInfo: String = "LocalData.Encryption" + defaultHKDFInfo: String = "LocalData.Encryption", + pbkdf2Iterations: Int = 10_000 ) { self.masterKeyService = masterKeyService self.masterKeyAccount = masterKeyAccount self.masterKeyLength = masterKeyLength self.defaultHKDFInfo = defaultHKDFInfo + self.pbkdf2Iterations = pbkdf2Iterations } public static let `default` = EncryptionConfiguration() diff --git a/Sources/LocalData/Models/SecurityPolicy.swift b/Sources/LocalData/Models/SecurityPolicy.swift index 3801bb2..6e95ec7 100644 --- a/Sources/LocalData/Models/SecurityPolicy.swift +++ b/Sources/LocalData/Models/SecurityPolicy.swift @@ -21,7 +21,7 @@ public enum SecurityPolicy: Sendable { } public enum KeyDerivation: Sendable { - case pbkdf2(iterations: Int, salt: Data? = nil) + case pbkdf2(iterations: Int? = nil, salt: Data? = nil) case hkdf(salt: Data? = nil, info: Data? = nil) } } diff --git a/Sources/LocalData/Services/EncryptionHelper.swift b/Sources/LocalData/Services/EncryptionHelper.swift index 1f61e8c..893c67b 100644 --- a/Sources/LocalData/Services/EncryptionHelper.swift +++ b/Sources/LocalData/Services/EncryptionHelper.swift @@ -104,10 +104,11 @@ actor EncryptionHelper { switch derivation { case .pbkdf2(let iterations, let customSalt): let salt = customSalt ?? defaultSalt(for: keyName) + let actualIterations = iterations ?? configuration.pbkdf2Iterations let derivedKeyData = try pbkdf2SHA256( password: baseKeyMaterial, salt: salt, - iterations: iterations, + iterations: actualIterations, keyLength: configuration.masterKeyLength ) return SymmetricKey(data: derivedKeyData)