ios - 在苹果钥匙串(keychain)中存储和读取密码的简单方法?

标签 ios swift keychain swift5

我想要一种简单的方法来使用 iOS 版 swift5 在苹果钥匙串(keychain)中存储和读取密码

Apple 关于钥匙串(keychain)的文档有点令人困惑 https://developer.apple.com/documentation/security/keychain_services/keychain_items/adding_a_password_to_the_keychain?language=swift

struct Credentials {
    var username: String
    var password: String
}
enum KeychainError: Error {
    case noPassword
    case unexpectedPasswordData
    case unhandledError(status: OSStatus)
}
struct Credentials {
        var username: String
        var password: String
    }

private func storeKeychain(username: String, password: String)throws->Any? {
        let credentials = Credentials.init(username: username, password: password)
        let query: [String: Any] = [kSecClass as String:  kSecClassGenericPassword,
                                    kSecValueData as String: credentials.password]

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

        return status
    }

private func getKeychain()throws ->String {
        let query: [String: Any] = [kSecClass as String: kSecClassGenericPassword,
                                    kSecMatchLimit as String: kSecMatchLimitOne,
                                    kSecReturnAttributes as String: true,
                                    kSecReturnData as String: true]
        var item: CFTypeRef?
        let status = SecItemCopyMatching(query as CFDictionary, &item)
        guard status != errSecItemNotFound else { throw KeychainError.noPassword }
        guard status == errSecSuccess else { throw KeychainError.unhandledError(status: status) }

        guard let existingItem = item as? [String : Any],
            let passwordData = existingItem[kSecValueData as String] as? Data,
            let password = String(data: passwordData, encoding: String.Encoding.utf8),
            let account = existingItem[kSecAttrAccount as String] as? String
            else {
                throw KeychainError.unexpectedPasswordData
        }
        _ = Credentials(username: account, password: password)
        return password
    }

override func viewDidLoad() {
        super.viewDidLoad()
           let keychains = try? storeKeychain(username: "John", password: "12345678")
        let password = try? getKeychain()
        print(password)
}

应打印 12345678 但打印可选(“f9dd6069-4e51-4c18-9dc6-7db6254271e3”)

最佳答案

您将密码作为字符串存储在钥匙串(keychain)中。我将修改 storeKeychain() 方法

private func storeKeychain(username: String, password: String) throws -> Any? {
    let credentials = Credentials.init(username: username, password: password)
    let data = credentials.password.data(using: .utf8)!

// store password as data and if you want to store username
    let query: [String: Any] = [kSecClass as String:  kSecClassGenericPassword,
                                kSecAttrAccount as String: username,
                                kSecValueData as String: data]
    let status = SecItemAdd(query as CFDictionary, nil)
    guard status == errSecSuccess else {
        throw KeychainError.unhandledError(status: status) }
    return status
}

检查是否有效。

关于ios - 在苹果钥匙串(keychain)中存储和读取密码的简单方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57129928/

相关文章:

ios - 我应该使用哪个 key 将密码存储在 iOS 钥匙串(keychain)中?

keychain - 在iOS10中,是否可以从静态库/框架内访问钥匙串(keychain),以进行单元测试

ios - 如何编译 iOS 应用程序 (IPA) 以通过 Microsoft Intune 分发它

ios - FaceBook API,应用内登录

ios - iOS后台流程

swift 'FIRInvalidArgumentException' ,原因 : 'Unsupported type: NSURL (found in field AccountTypeImageURL)'

ios - 如何在 swift 4 中检测 UILabel 中的链接?

macos - 运行需要从根终端访问钥匙串(keychain)的 cocoa 应用程序

ios - 如何在同一张图片的多种尺寸上实现相同的 CIFilter 效果

ios - 如何在 iOS 中获取正确的当前时间?