Simple Objective-C wrapper for the keychain that works on Mac and iOS

Last update: Jun 15, 2022

SAMKeychain

Version CocoaPods Carthage compatible

SAMKeychain is a simple wrapper for accessing accounts, getting passwords, setting passwords, and deleting passwords using the system Keychain on Mac OS X and iOS.

Adding to Your Project

Simply add the following to your Podfile if you're using CocoaPods:

pod 'SAMKeychain'

or Cartfile if you're using Carthage:

github "soffes/SAMKeychain"

To manually add to your project:

  1. Add Security.framework to your target
  2. Add SAMKeychain.h, SAMKeychain.m, SAMKeychainQuery.h, and SAMKeychainQuery.m to your project.

SAMKeychain requires ARC.

Note: Currently SAMKeychain does not support Mac OS 10.6.

Working with the Keychain

SAMKeychain has the following class methods for working with the system keychain:

+ (NSArray *)allAccounts;
+ (NSArray *)accountsForService:(NSString *)serviceName;
+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account;
+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account;
+ (void)setAccessibilityType:(CFTypeRef)accessibilityType;
+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account;

Easy as that. (See SAMKeychain.h and SAMKeychainQuery.h for all of the methods.)

Documentation

Use prepared documentation

Read the online documentation.

Debugging

If your saving to the keychain fails, use the NSError object to handle it. You can invoke [error code] to get the numeric error code. A few values are defined in SAMKeychain.h, and the rest in SecBase.h.

NSError *error = nil;
SAMKeychainQuery *query = [[SAMKeychainQuery alloc] init];
query.service = @"MyService";
query.account = @"soffes";
[query fetch:&error];

if ([error code] == errSecItemNotFound) {
    NSLog(@"Password not found");
} else if (error != nil) {
	NSLog(@"Some other error occurred: %@", [error localizedDescription]);
}

Obviously, you should do something more sophisticated. You can just call [error localizedDescription] if all you need is the error message.

Disclaimer

Working with the keychain is pretty sucky. You should really check for errors and failures. This library doesn't make it any more stable, it just wraps up all of the annoying C APIs.

You also really should not use the default but set the accessibilityType. kSecAttrAccessibleWhenUnlocked should work for most applications. See Apple Documentation for other options.

Thanks

This was originally inspired by EMKeychain and SDKeychain (both of which are now gone). Thanks to the authors. SAMKeychain has since switched to a simpler implementation that was abstracted from SSToolkit.

A huge thanks to Caleb Davenport for leading the way on version 1.0 of SAMKeychain.

GitHub

https://github.com/soffes/SAMKeychain
Comments
  • 1. Error -34018 (errSecDefault)

    Sometimes I'd see the following error

    (lldb) po error
    Error Domain=com.samsoffes.sskeychain Code=-34018 "errSecDefault" UserInfo=0x17d3f070 {NSLocalizedDescription=errSecDefault}
    

    But I have no idea what errSecDefault (code -34018) means nor how to resolve it. Any ideas?

    Reviewed by tonyxiao at 2013-12-03 07:49
  • 2. Keychain data seems to be disappearing

    SSKeychain has been working well for almost a year while I'm developing my app. I've run into a problem recently though that I haven't seem to be able to trace. Once in a while (and it seems random at times), the data I store in the keychain will now disappear. I'm not doing anything differently than before, so I'm not sure why the data isn't persisting.

    I'm currently on iOS 7.1.1 on an iPhone 5S. Using Xcode6-beta6 and AppCode 3.0.4.

    When I check [SSKeychain allAccounts] in debug, the array is empty.

    Here's my code to create a new device ID, for example:

    + (NSUUID *)getDeviceID:(BOOL)refresh {
        NSError *error;
        NSString *deviceKey = [self getAppConfiguration:refresh][DEVICE_KEY];
        NSString *deviceUUID = [SSKeychain passwordForService:KEYCHAIN_SERVICE_IDENTIFIER account:deviceKey error:&error];
        if (deviceUUID) {
            return [[NSUUID UUID] initWithUUIDString:deviceUUID];
        }
    
        if (error) {
            NSLog(@"Unable to retrieve the device ID because of an error: %@", [error localizedDescription]);
        }
    
        // one does not exist, so create one
        NSUUID *newUUID = [NSUUID UUID];
        deviceUUID = [newUUID UUIDString];
        [SSKeychain setPassword:deviceUUID forService:KEYCHAIN_SERVICE_IDENTIFIER account:deviceKey];
        return newUUID;
    }
    

    Anyone else see this happening or have some ideas on what might be causing the issue?

    Reviewed by abc2mit at 2014-09-02 05:38
  • 3. Fetch bleeds significant memory when called in a for loop.

    I tried calling the fetch command every .5 seconds to get one item (string with 4 characters) to test for memory bleeds. It starts to seriously eat at my applications memory and I have no idea why. My test code looks like this:

    -(void) infiniteLoop{

    NSError *error = nil;
    SSKeychainQuery * query = [[SSKeychainQuery alloc] init];
    query.service = @"test";
    query.account = @"loginPINForAccountID-2";
    query.password = nil;
    [query fetch:&error];
    
    @autoreleasepool {
        query = nil;
        error = nil;
    }
    
    [self performSelector:@selector(infiniteLoop) withObject:nil afterDelay:.5f];
    

    }

    Any advice here would be greatly appreciated.

    Reviewed by tylercrouch at 2015-10-21 18:26
  • 4. SSKeychainQuery::save failing on iOS 8

    Hi. I've run through the code with the debugger and this line is failing with return code -34018, which is currently undocumented.

    status = SecItemAdd((__bridge CFDictionaryRef)query, NULL);

    I hope this helps.

    Reviewed by mindbrix at 2014-06-10 07:26
  • 5. error : Error Domain=com.samsoffes.sskeychain Code=-34018 "errSecDefault" UserInfo=0x174e60a00 {NSLocalizedDescription=errSecDefault}

    Hi,

    When i use the method follow:

    + (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError *__autoreleasing *)error
    

    it appear error:

    error : Error Domain=com.samsoffes.sskeychain Code=-34018 "errSecDefault" UserInfo=0x174e60a00 {NSLocalizedDescription=errSecDefault}
    
    Reviewed by wanyakun at 2015-07-08 03:38
  • 6. Crashing on passwordObject

    I am using the code currently on the branch but when unarchiveObjectWithData: is called it causes an exception. I cannot explain it and I do not know how to get around it. The exception provides no information in the latest version of Xcode.

    Any ideas?

    • (id)passwordObject { if ([self.passwordData length]) { return [NSKeyedUnarchiver unarchiveObjectWithData:self.passwordData]; } return nil; }
    Reviewed by brennanMKE at 2013-04-17 01:43
  • 7. Storing an NSDictionary

    I need store an auth token and an integer value for the account so that I can work with a REST service with the app I am working on and storing these extra details in an NSDictionary along with the account would be useful.

    Since SSKeyChain does not have this feature I am jumping over to ACSimpleKeychain. Though I am strongly considering forking SSKeyChain and adding this functionality when I have the time. I can then send a Pull Request. If you'd like that please let me know.

    https://github.com/alexchugunov/ACSimpleKeychain

    Reviewed by brennanMKE at 2013-04-06 20:36
  • 8. setPassword:forService doesn't update old keys

    [SSKeychain setPassword:[passwordTextField stringValue] forService:@"" account:@"test"];
    

    It does work the first time, then it doesn't update the same key.

    Reviewed by kilianc at 2012-09-17 22:20
  • 9. New class design for performing easy keychain queries

    Add SSKeychainQuery class that takes an object-oriented approach so that new class methods with more and more parameters won't be needed every time a new feature is added.

    Reviewed by calebd at 2013-03-19 04:11
  • 10. Make the default security stronger

    In SSKeychain's doc it says for the AccessibilityType: If the value is NULL (the default), the Keychain default will be used. But I couldn't find in the apple docs what the default is and since this is a wrapper to make it easy for the user/developer I strongly think we should make it as save as possible and Apple recommends as well to always set kSecAttrAccessibleWhenUnlocked if possible.

    Reviewed by hashier at 2013-08-09 18:49
  • 11. Cannot get the password.

    When my app in background, and UIBackgroundTaskIdentifier value is UIBackgroundTaskInvalid, I use iOS 10.1.1 device(iPhone 6s or iPhone 6),I cannot get the password , I only get a nil. iOS 9.3.3 and iOS 9.3.5 is well. I'm New At iOS,so I want to find the answer.

    Reviewed by MattNeko at 2016-11-11 06:40
  • 12. iOS 12,iPhone X,Keychain data lost

    We store an encrypted string in keychain as the password for Touch ID or Face ID login,but some of our users fail to load this string which make them unable to use Touch ID/Face ID login, is there any bugs that will cause this problem.BTW,most of the abnormal devices are iPhone X with iOS 12.0.1

    Reviewed by qtechdrew at 2018-10-26 09:39
  • 13. iOS 12 Deprecated Issue

    Hi .. with iOS 12[NSKeyedArchiver archivedDataWithRootObject:object]; is Deprecated..

    - (void)setPasswordObject:(id<NSCoding>)object {
    	self.passwordData = [NSKeyedArchiver archivedDataWithRootObject:object];
    }
    

    are there any updates for SAMKeychain?

    Reviewed by CodeTeamLabs at 2018-10-02 18:25
  • 14. Update watchos deployment target for Xcode 10

    Hi, This PR is for Xcode 10 compatible.

    In Xcode 10 (GM or later), We need to update watchOS Deployment Target version to 3.0 or later. While using 2.0, We can build ipa but can't submit to App Store.

    Same issue is discussed in Forum: https://forums.developer.apple.com/thread/108408

    Thanks!

    Reviewed by shindyu at 2018-09-26 12:41
Simple Swift wrapper for Keychain that works on iOS, watchOS, tvOS and macOS.
Simple Swift wrapper for Keychain that works on iOS, watchOS, tvOS and macOS.

KeychainAccess KeychainAccess is a simple Swift wrapper for Keychain that works on iOS and OS X. Makes using Keychain APIs extremely easy and much mor

Jun 22, 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
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
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
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
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
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
TouchEncryptedJson - Simple project that accepts an input and encrypts it with the TouchID on a Mac

TouchEncryptedJson Simple project that accepts an input and encrypts it with the

Feb 11, 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
CCCryptor (AES encryption) wrappers for iOS and Mac in Swift. -- For ObjC, see RNCryptor/RNCryptor-objc

RNCryptor Cross-language AES Encryptor/Decryptor data format. The primary targets are Swift and Objective-C, but implementations are available in C, C

Jun 25, 2022
Automatically audit your Mac for basic security hygiene.
Automatically audit your Mac for basic security hygiene.

Automatically audit your Mac for basic security hygiene The simplest security is the most important. 80% of hacks are caused by 20% of common preventa

Jun 23, 2022
Virgil PFS SDK Objective-C/Swift
Virgil PFS SDK Objective-C/Swift

Virgil SWIFT PFS SDK Introduction | SDK Features | Installation | Initialization | Chat Example | Register Users | Docs | Support Introduction Virgil

Mar 16, 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