Simple Swift wrapper for Keychain that works on iOS, watchOS, tvOS and macOS.

Last update: Jun 22, 2022

KeychainAccess

Build Status Carthage compatible SPM supported Version Platform

KeychainAccess is a simple Swift wrapper for Keychain that works on iOS and OS X. Makes using Keychain APIs extremely easy and much more palatable to use in Swift.

πŸ’‘ Features

πŸ“– Usage

πŸ‘€ See also:

πŸ”‘ Basics

Saving Application Password

let keychain = Keychain(service: "com.example.github-token")
keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef"

Saving Internet Password

let keychain = Keychain(server: "https://github.com", protocolType: .https)
keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef"

πŸ”‘ Instantiation

Create Keychain for Application Password

let keychain = Keychain(service: "com.example.github-token")
let keychain = Keychain(service: "com.example.github-token", accessGroup: "12ABCD3E4F.shared")

Create Keychain for Internet Password

let keychain = Keychain(server: "https://github.com", protocolType: .https)
let keychain = Keychain(server: "https://github.com", protocolType: .https, authenticationType: .htmlForm)

πŸ”‘ Adding an item

subscripting

for String
keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef"
keychain[string: "kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef"
for NSData
keychain[data: "secret"] = NSData(contentsOfFile: "secret.bin")

set method

keychain.set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi")

error handling

do {
    try keychain.set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi")
}
catch let error {
    print(error)
}

πŸ”‘ Obtaining an item

subscripting

for String (If the value is NSData, attempt to convert to String)
let token = keychain["kishikawakatsumi"]
let token = keychain[string: "kishikawakatsumi"]
for NSData
let secretData = keychain[data: "secret"]

get methods

as String
let token = try? keychain.get("kishikawakatsumi")
let token = try? keychain.getString("kishikawakatsumi")
as NSData
let data = try? keychain.getData("kishikawakatsumi")

πŸ”‘ Removing an item

subscripting

keychain["kishikawakatsumi"] = nil

remove method

do {
    try keychain.remove("kishikawakatsumi")
} catch let error {
    print("error: \(error)")
}

πŸ”‘ Set Label and Comment

let keychain = Keychain(server: "https://github.com", protocolType: .https)
do {
    try keychain
        .label("github.com (kishikawakatsumi)")
        .comment("github access token")
        .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi")
} catch let error {
    print("error: \(error)")
}

πŸ”‘ Obtaining Other Attributes

PersistentRef

let keychain = Keychain()
let persistentRef = keychain[attributes: "kishikawakatsumi"]?.persistentRef
...

Creation Date

let keychain = Keychain()
let creationDate = keychain[attributes: "kishikawakatsumi"]?.creationDate
...

All Attributes

let keychain = Keychain()
do {
    let attributes = try keychain.get("kishikawakatsumi") { $0 }
    print(attributes?.comment)
    print(attributes?.label)
    print(attributes?.creator)
    ...
} catch let error {
    print("error: \(error)")
}
subscripting
let keychain = Keychain()
if let attributes = keychain[attributes: "kishikawakatsumi"] {
    print(attributes.comment)
    print(attributes.label)
    print(attributes.creator)
}

πŸ”‘ Configuration (Accessibility, Sharing, iCloud Sync)

Provides fluent interfaces

let keychain = Keychain(service: "com.example.github-token")
    .label("github.com (kishikawakatsumi)")
    .synchronizable(true)
    .accessibility(.afterFirstUnlock)

Accessibility

Default accessibility matches background application (=kSecAttrAccessibleAfterFirstUnlock)
let keychain = Keychain(service: "com.example.github-token")
For background application
Creating instance
let keychain = Keychain(service: "com.example.github-token")
    .accessibility(.afterFirstUnlock)

keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef"
One-shot
let keychain = Keychain(service: "com.example.github-token")

do {
    try keychain
        .accessibility(.afterFirstUnlock)
        .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi")
} catch let error {
    print("error: \(error)")
}
For foreground application
Creating instance
let keychain = Keychain(service: "com.example.github-token")
    .accessibility(.whenUnlocked)

keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef"
One-shot
let keychain = Keychain(service: "com.example.github-token")

do {
    try keychain
        .accessibility(.whenUnlocked)
        .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi")
} catch let error {
    print("error: \(error)")
}

πŸ‘« Sharing Keychain items

let keychain = Keychain(service: "com.example.github-token", accessGroup: "12ABCD3E4F.shared")

πŸ”„ Synchronizing Keychain items with iCloud

Creating instance
let keychain = Keychain(service: "com.example.github-token")
    .synchronizable(true)

keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef"
One-shot
let keychain = Keychain(service: "com.example.github-token")

do {
    try keychain
        .synchronizable(true)
        .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi")
} catch let error {
    print("error: \(error)")
}

πŸŒ€ Touch ID (Face ID) integration

Any Operation that require authentication must be run in the background thread.
If you run in the main thread, UI thread will lock for the system to try to display the authentication dialog.

To use Face ID, add NSFaceIDUsageDescription key to your Info.plist

πŸ” Adding a Touch ID (Face ID) protected item

If you want to store the Touch ID protected Keychain item, specify accessibility and authenticationPolicy attributes.

let keychain = Keychain(service: "com.example.github-token")

DispatchQueue.global().async {
    do {
        // Should be the secret invalidated when passcode is removed? If not then use `.WhenUnlocked`
        try keychain
            .accessibility(.whenPasscodeSetThisDeviceOnly, authenticationPolicy: .userPresence)
            .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi")
    } catch let error {
        // Error handling if needed...
    }
}

πŸ” Updating a Touch ID (Face ID) protected item

The same way as when adding.

Do not run in the main thread if there is a possibility that the item you are trying to add already exists, and protected. Because updating protected items requires authentication.

Additionally, you want to show custom authentication prompt message when updating, specify an authenticationPrompt attribute. If the item not protected, the authenticationPrompt parameter just be ignored.

let keychain = Keychain(service: "com.example.github-token")

DispatchQueue.global().async {
    do {
        // Should be the secret invalidated when passcode is removed? If not then use `.WhenUnlocked`
        try keychain
            .accessibility(.whenPasscodeSetThisDeviceOnly, authenticationPolicy: .userPresence)
            .authenticationPrompt("Authenticate to update your access token")
            .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi")
    } catch let error {
        // Error handling if needed...
    }
}

πŸ” Obtaining a Touch ID (Face ID) protected item

The same way as when you get a normal item. It will be displayed automatically Touch ID or passcode authentication If the item you try to get is protected.
If you want to show custom authentication prompt message, specify an authenticationPrompt attribute. If the item not protected, the authenticationPrompt parameter just be ignored.

let keychain = Keychain(service: "com.example.github-token")

DispatchQueue.global().async {
    do {
        let password = try keychain
            .authenticationPrompt("Authenticate to login to server")
            .get("kishikawakatsumi")

        print("password: \(password)")
    } catch let error {
        // Error handling if needed...
    }
}

πŸ” Removing a Touch ID (Face ID) protected item

The same way as when you remove a normal item. There is no way to show Touch ID or passcode authentication when removing Keychain items.

let keychain = Keychain(service: "com.example.github-token")

do {
    try keychain.remove("kishikawakatsumi")
} catch let error {
    // Error handling if needed...
}

πŸ”‘ Shared Web Credentials

Shared web credentials is a programming interface that enables native iOS apps to share credentials with their website counterparts. For example, a user may log in to a website in Safari, entering a user name and password, and save those credentials using the iCloud Keychain. Later, the user may run a native app from the same developer, and instead of the app requiring the user to reenter a user name and password, shared web credentials gives it access to the credentials that were entered earlier in Safari. The user can also create new accounts, update passwords, or delete her account from within the app. These changes are then saved and used by Safari.
https://developer.apple.com/library/ios/documentation/Security/Reference/SharedWebCredentialsRef/

let keychain = Keychain(server: "https://www.kishikawakatsumi.com", protocolType: .HTTPS)

let username = "[email protected]"

// First, check the credential in the app's Keychain
if let password = try? keychain.get(username) {
    // If found password in the Keychain,
    // then log into the server
} else {
    // If not found password in the Keychain,
    // try to read from Shared Web Credentials
    keychain.getSharedPassword(username) { (password, error) -> () in
        if password != nil {
            // If found password in the Shared Web Credentials,
            // then log into the server
            // and save the password to the Keychain

            keychain[username] = password
        } else {
            // If not found password either in the Keychain also Shared Web Credentials,
            // prompt for username and password

            // Log into server

            // If the login is successful,
            // save the credentials to both the Keychain and the Shared Web Credentials.

            keychain[username] = inputPassword
            keychain.setSharedPassword(inputPassword, account: username)
        }
    }
}

Request all associated domain's credentials

Keychain.requestSharedWebCredential { (credentials, error) -> () in

}

Generate strong random password

Generate strong random password that is in the same format used by Safari autofill (xxx-xxx-xxx-xxx).

let password = Keychain.generatePassword() // => Nhu-GKm-s3n-pMx

How to set up Shared Web Credentials

  1. Add a com.apple.developer.associated-domains entitlement to your app. This entitlement must include all the domains with which you want to share credentials.

  2. Add an apple-app-site-association file to your website. This file must include application identifiers for all the apps with which the site wants to share credentials, and it must be properly signed.

  3. When the app is installed, the system downloads and verifies the site association file for each of its associated domains. If the verification is successful, the app is associated with the domain.

More details:
https://developer.apple.com/library/ios/documentation/Security/Reference/SharedWebCredentialsRef/

πŸ” Debugging

Display all stored items if print keychain object

let keychain = Keychain(server: "https://github.com", protocolType: .https)
print("\(keychain)")
=>
[
  [authenticationType: default, key: kishikawakatsumi, server: github.com, class: internetPassword, protocol: https]
  [authenticationType: default, key: hirohamada, server: github.com, class: internetPassword, protocol: https]
  [authenticationType: default, key: honeylemon, server: github.com, class: internetPassword, protocol: https]
]

Obtaining all stored keys

let keychain = Keychain(server: "https://github.com", protocolType: .https)

let keys = keychain.allKeys()
for key in keys {
  print("key: \(key)")
}
=>
key: kishikawakatsumi
key: hirohamada
key: honeylemon

Obtaining all stored items

let keychain = Keychain(server: "https://github.com", protocolType: .https)

let items = keychain.allItems()
for item in items {
  print("item: \(item)")
}
=>
item: [authenticationType: Default, key: kishikawakatsumi, server: github.com, class: InternetPassword, protocol: https]
item: [authenticationType: Default, key: hirohamada, server: github.com, class: InternetPassword, protocol: https]
item: [authenticationType: Default, key: honeylemon, server: github.com, class: InternetPassword, protocol: https]

Keychain sharing capability

If you encounter the error below, you need to add an Keychain.entitlements.

OSStatus error:[-34018] Internal error when a required entitlement isn't present, client has neither application-identifier nor keychain-access-groups entitlements.

Screen Shot 2019-10-27 at 8 08 50

Requirements

OS Swift
v1.1.x iOS 7+, macOS 10.9+ 1.1
v1.2.x iOS 7+, macOS 10.9+ 1.2
v2.0.x iOS 7+, macOS 10.9+, watchOS 2+ 2.0
v2.1.x iOS 7+, macOS 10.9+, watchOS 2+ 2.0
v2.2.x iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ 2.0, 2.1
v2.3.x iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ 2.0, 2.1, 2.2
v2.4.x iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ 2.2, 2.3
v3.0.x iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ 3.x
v3.1.x iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ 4.0, 4.1, 4.2
v3.2.x iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ 4.0, 4.1, 4.2, 5.0
v4.0.x iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ 4.0, 4.1, 4.2, 5.1
v4.1.x iOS 8+, macOS 10.9+, watchOS 3+, tvOS 9+, Mac Catalyst 13+ 4.0, 4.1, 4.2, 5.1

Installation

CocoaPods

KeychainAccess is available through CocoaPods. To install it, simply add the following lines to your Podfile:

use_frameworks!
pod 'KeychainAccess'

Carthage

KeychainAccess is available through Carthage. To install it, simply add the following line to your Cartfile:

github "kishikawakatsumi/KeychainAccess"

Swift Package Manager

KeychainAccess is also available through Swift Package Manager.

Xcode

Select File > Swift Packages > Add Package Dependency...,

CLI

First, create Package.swift that its package declaration includes:

// swift-tools-version:5.0
import PackageDescription

let package = Package(
    name: "MyLibrary",
    products: [
        .library(name: "MyLibrary", targets: ["MyLibrary"]),
    ],
    dependencies: [
        .package(url: "https://github.com/kishikawakatsumi/KeychainAccess.git", from: "3.0.0"),
    ],
    targets: [
        .target(name: "MyLibrary", dependencies: ["KeychainAccess"]),
    ]
)

Then, type

$ swift build

To manually add to your project

  1. Add Lib/KeychainAccess.xcodeproj to your project
  2. Link KeychainAccess.framework with your target
  3. Add Copy Files Build Phase to include the framework to your application bundle

See iOS Example Project as reference.

Author

kishikawa katsumi, [email protected]

License

KeychainAccess is available under the MIT license. See the LICENSE file for more info.

GitHub

https://github.com/kishikawakatsumi/KeychainAccess
Comments
  • 1. Error -34018 required entitlement

    Hello,

    I'm frequently getting this error:

    Error Domain=com.kishikawakatsumi.KeychainAccess.error Code=-34018 "Internal error when a required entitlement isn't present, client has neither application-identifier nor keychain-access-groups entitlements."

    I noticed it tends to happen when the application comes back from Background. Any idea where this could come from?

    Reviewed by arnaudmeunier at 2015-02-19 17:11
  • 2. Disable passcode entry completely

    I have tried disabling by using policy authenticationPolicy: .biometryCurrentSet and authenticationPolicy: .biometryAny but after three failed attempts the app asks for a passcode. How do I remove passcode completely?

    Reviewed by kipropkorir at 2020-04-28 09:51
  • 3. Application has issues with line 537 let status = SecItemCopyMatching(query as CFDictionary, &result)

    Each time my application opens which has a breakpoint for any errors this line stops execution for some reason:

        let status = SecItemCopyMatching(query as CFDictionary, &result)
    

    Any ideas what may be going wrong?

    Reviewed by dkalinai at 2018-03-05 08:52
  • 4. OSStatus error:[-50] with Xcode 8 and swift3

    I make main app and today extension. I'm using keychain for personal data. so, when i save data in keychain, i did use Keychain(service: , accessGroup: ) and KeychainAccess ver 3.0.1

    //save action @IBAction func btnSave(_ sender: UIButton) { let keychain = Keychain(service: "ABC", accessGroup: "*") keychain[data: keyname] = NSData(data: UIImagePNGRepresentatioin(image)) as Data }

    //get list personal data (in tableViewController)

    let keychain = Keychain(service: "ABC", accessGroup: "*")

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequ..... cell.textLabel.text = "(keychain.allKeys()[indexPath.row])" return cell }

    sometimes, save data in keychain successfully and show data list. But when one or more data saved in keychain, i can't show data list and show this error message. "osstatus error:[-50] One or more parameters passed to a function were not valid. "

    Reviewed by Dev-MJ at 2016-10-24 06:09
  • 5. KeychainAccess return sometimes empty value

    I have a Issue which I don't really understand sometimes the Keychain is empty without any reason. Look's like I have the same Issue like this http://stackoverflow.com/questions/36285783/keychain-sometimes-returns-empty-value

    Other people with the same issue ?

    I observed some other app's like Telegram or Slack where I was kick out sometimes maybe it's a issue from Keychain from Apple. I'm not really sure.. :/

    Reviewed by BilalReffas at 2016-09-16 20:14
  • 6. Keychain on iOS

    Hi, spoke to you via email - I'm not using you code but hope you might be able to give me some insight into an issue with the C API. I'm not a swift programmer, but think we're basically doing the same thing.

        CFMutableDictionaryRef query = CFDictionaryCreateMutable( nullptr, 10, nullptr, nullptr );
        CFDictionaryAddValue( query, kSecClass, kSecClassGenericPassword );
        CFDictionaryAddValue( query, kSecAttrAccount, "test" );
        CFDictionaryAddValue( query, kSecValueData, "data" );
    
        const auto res = SecItemAdd( query, nullptr );
    

    This code works fine on Mac, but returns error -50 on iOS, which is errSecParam. Looking through you code it seems this should be supported on iOS.

    Cheers

    Reviewed by leehu at 2020-05-05 14:35
  • 7. Change SPM library to dynamic instead of static

    Hi, since Xcode 11.4b1 I'm unable to use KeychainAccess imported using SwiftPM in main app target and Today widget target at the same time. It's because SwiftPM by default imports dependencies as static library. Is there a chance to update Package.swift manifest to produce dynamic framework? I found out it should be pretty simple and I can send PR if your are open to it.

    Reviewed by marekpridal at 2020-02-17 15:21
  • 8. Could not locate installed application Install claimed to have succeeded

    today, My Colleague and I are carthage update for our project.

    build our project is OK, but can't install device

    we replace old framework step by step, and found out KeychainAccess.framework cause the error.

    Xcode alert message: Could not locate installed application Install claimed to have succeeded

    Xcode 11.1 KeychainAccess tag: v3.2.1

    Reviewed by astroboy0803 at 2019-10-29 09:22
  • 9. Should i call something like synchronize like UserDefaults?

    Sometimes seems the tokens are not saved or i can't read them? This class its correct?

    import KeychainAccess

    class DataStorage {

        private static let keychain = Keychain(service: Identifiers.GCalendar)
    
        private struct Identifiers {
            static let GCalendar = "OAuthGoogleCalendar"
            static let token = "the_token_key1"
            static let secretToken = "the_secret_token_key1"
        }
    
        class func saveTokens(token: String, secretToken: String) {
            keychain[string: Identifiers.token] = token
            keychain[string: Identifiers.secretToken] = secretToken
        }
    
        @discardableResult
        class func getTokens() -> (token: String, secretToken: String) {
            return (keychain[Identifiers.token] ?? "", keychain[Identifiers.secretToken] ?? "")
        }
    
        class func existsToken() -> Bool {
            return keychain[Identifiers.token]  != nil
        }
    
        class func removeTokens() {
            do {
                try keychain.remove(Identifiers.token)
                try keychain.remove(Identifiers.secretToken)
            } catch let error {
                print("error removing tokens \(error.localizedDescription)")
            }
        }
    

    }

    Reviewed by ivanruizscm at 2016-10-03 15:07
  • 10. Support Swift 3.0

    Support Swift 3.0

    • [x] id is now mapped to Any

      [SE-0116] Import Objective-C id as Swift Any type

    • [x] OptionSetType => OptionSet

    • [x] ErrorType => ErrorProtocol => Error

    • [x] AuthenticationPolicy to be UInt

    • [x] Drop NS prefix

      • [x] NSData => Data
      • [x] NSURL => URL
      • [x] NSIndexSet => IndexSet
    • [x] Lowercase enums (adn OptionSet types)

    Update to Xcode 8 recommended build settings

    • [x] Enable whole module optimazatin (by default on Xcode 8)
    • [x] New code signing

    Tests on Travis CI with Xcode 8beta

    • [x] Fix code signing issue

    Bug fixes

    • [x] Enable to catch specific errors
    Reviewed by kishikawakatsumi at 2016-06-28 00:37
  • 11. Check if item exists in keychain without Touch ID auth

    Is this possible? Is it possible to see if a value exists at a given key in a keychain secured with Touch ID without prompting the user for their finger print?

    If not, is there a way to check if the keychain, as a whole, exists without prompting for authentication?

    I was torn as to whether I should ask this on here or on StackOverflow. I hope you don't mind me asking here? :innocent: :sweat_smile:. I figured since I'm using your framework and couldn't find anything about my question in the README, I'd be coming back to you with any answer I got on SO to see how I do it via KeychainAccess.

    Many thanks!

    Reviewed by ky1ejs at 2015-10-27 14:19
  • 12. Question: detecting compromised passwords/items

    iOS recently introduced the ability to see compromised logins in settings from keychain.

    Would it be possible to detect that a user has any of these. I'd be looking just for an event/loop to determine they have some and nothing more, not the login/details just that the compromised logins exist.

    Reviewed by StuartMorris0 at 2022-04-27 14:03
  • 13. Fix macOS Access Groups

    When using Access Groups on macOS kSecUseDataProtectionKeychain needs to be set to true:

    https://developer.apple.com/documentation/security/ksecusedataprotectionkeychain

    Set the value for this key to true in the query dictionary when accessing a macOS keychain item that behaves like an iOS keychain item. For example, use the data protection key when adding, searching for, or deleting an item to which the kSecAttrAccessible or kSecAttrAccessGroup attributes apply.

    The data protection key affects operations only in macOS. Other platforms automatically behave as if the key is set to true, and ignore the key in the query dictionary. You can safely use the key on all platforms.

    Tip It’s highly recommended that you set the value of this key to true for all keychain operations. This key helps to improve the portability of your code across platforms. Use it unless you specifically need access to items previously stored in a legacy keychain in macOS.

    This pull request is a first fix for issues #438, #491 and #535

    Reviewed by rivera-ernesto at 2022-02-15 18:37
  • 14. Usage with SwiftUI

    Hello,

    does anyone uses the package with SwiftUI? Everything works so far, but changes are not fetched in the background. I have a list that contains the values from the allKeys()-methods. So if I add a new password, the list doesn't update because the new password isn't fetched. Same for cloud-sync. If there is a new key in the cloud, I have to call the allKeys()-method manually to fetch changes. How can I do that automatically?

    Help would be great :)

    Reviewed by Elektronenhirn108 at 2022-02-09 20:46
  • 15. Catch Touch ID prompt canceled by user

    Hello,

    I can't manage to catch if a user canceled the touch ID / password prompt => the key is always returned, as nil if the user canceled the prompt.

    That's a major issue because if the key is nil, I (later in the code) assume there is none and so I create it: => so in fact I modify it => meaning basically if the user cancel the prompt, its key is updated....

    I'm working on a MacOS app.

    Any idea? Thanks.

    func findKeychainKey(identifier: String) throws -> Data? {
        let keychain = Keychain(service: "XXXX", accessGroup: "XXXX")
        do {
            let findKey = try keychain.getData(identifier)
            return findKey! // always ends here, either the key is found or not, or even if the user cancel the touch ID / password prompt
        } catch (Status.userCanceled) {
            // A user canceled the touch ID / password prompt
            print("The user canceled the touch ID / password prompt.")
            throw KeychainError.userCancelled
        } catch let error {
            print("error: \(error)")
            throw KeychainError.emptyKey
        }
    }
    

    Linked to https://github.com/kishikawakatsumi/KeychainAccess/issues/338

    Reviewed by Ontokrat at 2022-01-19 22:37
  • 16. Removed explicit platforms definition from Package.swift

    This resolves IPHONEOS_DEPLOYMENT_TARGET warnings in newer Xcode versions. See https://github.com/nanopb/nanopb/pull/585 for reference β€” I assume the same applies for this project. The toolchain will this way always choose the latest supported platform version.

    Reviewed by simonseyer at 2021-12-02 13:07
Simple Objective-C wrapper for the keychain that works on Mac and iOS

SAMKeychain SAMKeychain is a simple wrapper for accessing accounts, getting passwords, setting passwords, and deleting passwords using the system Keyc

Jun 15, 2022
A wrapper to make it really easy to deal with iOS, macOS, watchOS and Linux Keychain and store your user's credentials securely.

A wrapper (written only in Swift) to make it really easy to deal with iOS, macOS, watchOS and Linux Keychain and store your user's credentials securely.

Mar 29, 2022
A simple Swift Keychain Wrapper for iOS, watchOS, and OS X.

Latch A simple Swift 2.0 Keychain Wrapper for iOS, watchOS 2, and OS X. Usage A proper example of how to use Latch can be seen in the tests. import La

Jan 29, 2022
Helper functions for saving text in Keychain securely for iOS, OS X, tvOS and watchOS.
Helper functions for saving text in Keychain securely for iOS, OS X, tvOS and watchOS.

Helper functions for storing text in Keychain for iOS, macOS, tvOS and WatchOS This is a collection of helper functions for saving text and data in th

Jun 21, 2022
A simple wrapper for the iOS Keychain to allow you to use it in a similar fashion to User Defaults. Written in Swift.

SwiftKeychainWrapper A simple wrapper for the iOS / tvOS Keychain to allow you to use it in a similar fashion to User Defaults. Written in Swift. Prov

Jun 25, 2022
A really simple key-value wrapper for keychain.

PlainKeychain A really simple key-value wrapper for keychain. Features βœ… Key-value pairs using kSecClassGenericPassword. ❌ Internet passwords (kSecCla

Nov 27, 2021
RSA public/private key encryption, private key signing and public key verification in Swift using the Swift Package Manager. Works on iOS, macOS, and Linux (work in progress).

BlueRSA Swift cross-platform RSA wrapper library for RSA encryption and signing. Works on supported Apple platforms (using Security framework). Linux

May 31, 2022
RSA public/private key encryption, private key signing and public key verification in Swift using the Swift Package Manager. Works on iOS, macOS, and Linux (work in progress).

BlueRSA Swift cross-platform RSA wrapper library for RSA encryption and signing. Works on supported Apple platforms (using Security framework). Linux

May 31, 2022
Generate passwords and save them in Keychain. Made with SwiftUI.
Generate passwords and save them in Keychain. Made with SwiftUI.

lockd Generate strong passwords and save them in Keychain. Join lockd Beta on TestFlight: https://testflight.apple.com/join/xJ5AlvS3 Features: Generat

Jun 6, 2022
A powerful, protocol-oriented library for working with the keychain in Swift.

Locksmith A powerful, protocol-oriented library for working with the keychain in Swift. ?? iOS 8.0+ ?? Mac OS X 10.10+ ⌚️ watchOS 2 ?? tvOS ?? I make

Jun 17, 2022
KeyClip is yet another Keychain library written in Swift.

KeyClip KeyClip is yet another Keychain library written in Swift. Features Multi Types ( String / NSDictionary / NSData ) Error Handling Settings ( kS

Feb 2, 2022
Very simple swift wrapper for Biometric Authentication Services (Touch ID) on iOS.

SimpleTouch Very simple swift wrapper for Biometric Authentication Services (Touch ID) on iOS. Sample Project There is a SimpleTouchDemo target define

Mar 18, 2022
The IDAGIO WatchOS app using swift
The IDAGIO WatchOS app using swift

IDAGIORedesignWatchOS I redesigned the IDAGIO WatchOS app as an exercise Old App

Dec 23, 2021
A wrapper for Apple's Common Crypto library written in Swift.

IDZSwiftCommonCrypto A Swift wrapper for Apple's CommonCrypto library. IDZSwiftCommonCrypto works with both CocoaPods and Cathage. For more details on

Apr 8, 2022
Helper/wrapper for mautrix-imessage for jailbroken devices

Brooklyn This readme is out-of-date. Blame Ethan, he's working on it. Components Rubicon "The die is cast." Crosses Apple's last river between IMCore

May 17, 2022
Wrapper class for handling all tasks related to RSA cryptography

RSAWrapper Wrapper class for handling all tasks related to RSA cryptography USAG

Dec 24, 2021
A super simple tool for macOS Swift developers to check validity of a Gumroad-issued software license keys

Gumroad License Validator Overview A super simple tool for macOS Swift developers to check validity of a Gumroad-issued software license keys Requirem

May 15, 2022
Safe and easy to use crypto for iOS and macOS

Swift-Sodium Swift-Sodium provides a safe and easy to use interface to perform common cryptographic operations on macOS, iOS, tvOS and watchOS. It lev

Jun 15, 2022
Native and encrypted password manager for iOS and macOS.
Native and encrypted password manager for iOS and macOS.

Open Sesame Native and encrypted password manager for iOS and macOS. What is it? OpenSesame is a free and powerful password manager that lets you mana

Jun 26, 2022