kSecAttrAccount 和 kSecAttrGeneric

kSecAttrAccount and kSecAttrGeneric

我想在帐户 marta@domain.com 中保存两个值。词典示例:

kSecAttrAccount = 玛塔@domain.com

kSecAttrGeneric = value1Key

kSecValueData = value1

kSecAttrAccount = 玛塔@domain.com

kSecAttrGeneric = value2Key

kSecValueData = value2


可能吗?当我尝试保留第二个值时,我在执行查询时遇到错误。

我附上我的代码片段:

func addCredentials(_ credentials: KeychainCredentials) throws {

let account = credentials.account
let password = credentials.password.data(using: String.Encoding.utf8)!
let generic = credentials.generic

 let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, 
            kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
            .userPresence,
            nil) 

 // Build the query
 let query: [String: Any] = [kSecClass as String: kSecClassGenericPassword,
                                    kSecAttrService as String: serviceName,
                                    kSecAttrAccount as String: account,
                                    kSecAttrGeneric as String: generic,
                                    kSecAttrAccessControl as String: accessControl as Any,
                                    kSecValueData as String: password]

let status = SecItemAdd(query as CFDictionary, nil)
guard status == errSecSuccess else { throw KeychainError(status: status) }

}

对于kSecClassGenericPassword,服务和帐户的组合必须是唯一的。有关哪些属性是主键的一部分的列表,请参阅 errSecDuplicateItem.

的文档

The system considers an item to be a duplicate for a given keychain when that keychain already has an item of the same class with the same set of composite primary keys. Each class of keychain item has a different set of primary keys, although a few attributes are used in common across all classes. In particular, where applicable, kSecAttrSynchronizable and kSecAttrAccessGroup are part of the set of primary keys. The additional per-class primary keys are listed below:

For generic passwords, the primary keys include kSecAttrAccount and kSecAttrService.

For internet passwords, the primary keys include kSecAttrAccount, kSecAttrSecurityDomain, kSecAttrServer, kSecAttrProtocol, kSecAttrAuthenticationType, kSecAttrPort, and kSecAttrPath.

For certificates, the primary keys include kSecAttrCertificateType, kSecAttrIssuer, and kSecAttrSerialNumber.

For key items, the primary keys include kSecAttrKeyClass, kSecAttrKeyType, kSecAttrApplicationLabel, kSecAttrApplicationTag, kSecAttrKeySizeInBits, and kSecAttrEffectiveKeySize.

For identity items, which are a certificate and a private key bundled together, the primary keys are the same as for a certificate. Because a private key may be certified more than once, the uniqueness of the certificate determines that of the identity.

如果我正在构建它,我可能会将所有 key/values 放入字典中,并将其序列化为单个 kSecAttrAccount 记录。

或者,您可以将您的帐户和服务值合并到帐户中(如果您有服务),然后将 value1Key 放入服务属性中。然后帐户+服务对于给定的密钥将是唯一的。