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

Overview

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.

Comments
  • Error -34018 (errSecDefault)

    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?

    opened by tonyxiao 111
  • Keychain data seems to be disappearing

    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?

    opened by abc2mit 22
  • Fetch bleeds significant memory when called in a for loop.

    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.

    opened by tylercrouch 18
  • SSKeychainQuery::save failing on iOS 8

    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.

    opened by mindbrix 14
  • error : Error Domain=com.samsoffes.sskeychain Code=-34018

    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}
    
    question 
    opened by wanyakun 13
  • Crashing on passwordObject

    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; }
    opened by brennanMKE 13
  • Storing an NSDictionary

    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

    opened by brennanMKE 13
  • setPassword:forService doesn't update old keys

    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.

    opened by kilianc 13
  • New class design for performing easy keychain queries

    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.

    opened by calebd 11
  • Make the default security stronger

    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.

    opened by hashier 10
  • Cannot get the password.

    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.

    opened by MattNeko 9
  • iOS 12,iPhone X,Keychain data lost

    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

    opened by qtechdrew 5
  • iOS 12 Deprecated Issue

    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?

    opened by CodeTeamLabs 0
  • Update watchos deployment target for Xcode 10

    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!

    opened by shindyu 0
Releases(v1.5.2)
Owner
Sam Soffes
Building things
Sam Soffes
UICKeyChainStore is a simple wrapper for Keychain on iOS, watchOS, tvOS and macOS. Makes using Keychain APIs as easy as NSUserDefaults.

UICKeyChainStore UICKeyChainStore is a simple wrapper for Keychain that works on iOS and OS X. Makes using Keychain APIs as easy as NSUserDefaults. Lo

Kishikawa Katsumi 3.1k Dec 28, 2022
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

Kishikawa Katsumi 7.2k Jan 5, 2023
Keychain - Keychain wrapper with swift

Keychain wrapper. Store a value as a generic password: let account = "an-arbitra

Alejandro Ramirez 0 Mar 14, 2022
A Layer-2 framework built over Keychain API which helps in using Keychain in all your Apple devices with easiness and flexibility.

Keychain Manager Keychain Manager is a Layer-2 framework built over Keychain API which helps in using Keychain in all your Apple devices with easiness

Gokul Nair 14 Jan 1, 2023
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

Jason 1.5k Jan 8, 2023
A keychain wrapper that is so easy to use that your cat could use it.

A keychain wrapper that is so easy to use that your cat could use it.

HyperRedink 71 Oct 15, 2022
Modern Swift wrapper for Keychain Services API with the benefits of static typing

SwiftyKeychainKit SwiftyKeychainKit is a simple Swift wrapper for Keychain Services API with the benefits of static typing. Define your keys in one pl

Andriy Slyusar 18 Jan 1, 2023
Example of using TOTP with iCloud Keychain in iOS 15

Installation This example needs Ngrok and Ruby 3.0.3+. Setup project with Makefi

Makeeyaf 0 Dec 31, 2021
A tool to check which keychain items are available to an attacker once an iOS device has been jailbroken

Keychain Dumper Usage All that should be needed to use keychain_dumper is the binary that is checked in to the Keychain-Dumper Git repository. This bi

Patrick Toomey 1.2k Dec 28, 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

Matthew Palmer 2.9k Dec 21, 2022
Recover lost keychain passwords with swift

brutalkeychain Recover lost keychain passwords using a simple swift script (so c

Charles Edge 9 Sep 12, 2022
Recover lost keychain passwords with swift

brutalkeychain Recover lost keychain passwords using a simple swift script (so c

Charles Edge 4 Dec 24, 2021
Objective-C utility class for storing data securely in the key chain.

Lockbox Lockbox is an Objective-C utility class for storing data securely in the keychain. Use it to store small, sensitive bits of data securely. Loo

Mark Granoff 858 Sep 8, 2022
Keep track of accessibility settings, leverage high contrast colors, and use scalable fonts to enable users with disabilities to use your app.

Accessibility for iOS, macOS, tvOS, and watchOS ?? What's new in Capable 2.0 ?? Here are the most important changes: ?? New framework architecture and

Christoph Wendt 230 Jan 4, 2023
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

Sam Soffes 5.4k Jan 8, 2023
Valet lets you securely store data in the iOS, tvOS, or macOS Keychain without knowing a thing about how the Keychain works.

Valet Valet lets you securely store data in the iOS, tvOS, watchOS, or macOS Keychain without knowing a thing about how the Keychain works. It’s easy.

Square 3.8k Jan 4, 2023
Valet lets you securely store data in the iOS, tvOS, or macOS Keychain without knowing a thing about how the Keychain works. It’s easy. We promise.

Valet Valet lets you securely store data in the iOS, tvOS, watchOS, or macOS Keychain without knowing a thing about how the Keychain works. It’s easy.

Square 3.8k Jan 4, 2023
UICKeyChainStore is a simple wrapper for Keychain on iOS, watchOS, tvOS and macOS. Makes using Keychain APIs as easy as NSUserDefaults.

UICKeyChainStore UICKeyChainStore is a simple wrapper for Keychain that works on iOS and OS X. Makes using Keychain APIs as easy as NSUserDefaults. Lo

Kishikawa Katsumi 3.1k Dec 28, 2022
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

Kishikawa Katsumi 7.2k Dec 30, 2022
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

Kishikawa Katsumi 7.2k Jan 5, 2023