Friday, September 11, 2015

Simple Xamarin iOS Keychain code

I had searched and found a few decent examples of KeyChain (iOS) usage in Xamarin

I had searched and found a few decent examples of KeyChain (iOS) usage in Xamarin but not exactly the code I was happy with.

So this is more of a mashup of pieces of the good code I found formed into one utility class.

The key essentials are find an existing key, create a new key, delete a previous key. The examples I saw tried to do all of this in one method, it's better to break things up, have one method per responsilibity.

using Security;
using Foundation;

public class KeyChain
{

    public string ValueForKey(string key)
    {
        var record = ExistingRecordForKey (key);
        SecStatusCode resultCode;
        var match = SecKeyChain.QueryAsRecord(record, out resultCode);

        if (resultCode == SecStatusCode.Success)
            return NSString.FromData (match.ValueData, NSStringEncoding.UTF8);
        else
            return String.Empty;
    }

    public void SetValueForKey(string value, string key) 
    {
        var record = ExistingRecordForKey (key);            
        if (value.IsNullOrEmpty())
        {
            if (!ValueForKey(key).IsNullOrEmpty())
                RemoveRecord(record);

            return;
        }

        // if the key already exists, remove it
        if (!ValueForKey(key).IsNullOrEmpty())
            RemoveRecord(record);

        var result = SecKeyChain.Add(CreateRecordForNewKeyValue(key, value));
        if (result != SecStatusCode.Success)
        {
            throw new Exception(String.Format("Error adding record: {0}", result));
        }
    }

    private SecRecord CreateRecordForNewKeyValue(string key, string value)
    {
        return new SecRecord(SecKind.GenericPassword)
        {
            Account = key,
            Service = ServiceName,
            Label = key,
            ValueData = NSData.FromString(value, NSStringEncoding.UTF8),
        };
    }

    private SecRecord ExistingRecordForKey(string key)
    {
        return new SecRecord(SecKind.GenericPassword)
        {
            Account = key,
            Service = ServiceName,
            Label = key,
        };
    }

    private bool RemoveRecord(SecRecord record)
    {
        var result = SecKeyChain.Remove(record);
        if (result != SecStatusCode.Success)
        {
            throw new Exception(String.Format("Error removing record: {0}", result));
        }

        return true;
    }        
}

9 comments:

  1. Thank you so much Mark! I just spent the last three hours looking for something this simple. Most examples I had found seemed overly complicated and not generic enough to handle simple key/value data. I can't believe there aren't more examples of using Keychain for Xamarin iOS out there, anyways thank you!

    ReplyDelete
  2. Can You Provide Example of "How to share Keychain between iOS apps in XAMARIN"
    Reference:
    http://stackoverflow.com/questions/4115744/how-to-share-keychain-data-between-ios-applications
    http://evgenii.com/blog/sharing-keychain-in-ios/

    ReplyDelete
  3. what is ServiceName in your code? thanks!

    ReplyDelete
    Replies
    1. Actually not sure, I believe it's an extra value I forgot to take out of the code, there is a Service property on the SecRecord and you can set it to whatever you like. So you could pass in another string into the method (key, value, serviceName). I believe the purpose of Service separates the sets of key values into groups by Service.

      Delete
  4. Hi mark.
    Your explanation is great. However i'm trying to do something similar but with a bit difference.
    Could you please read my thread here

    https://stackoverflow.com/questions/49381392/c-sharp-how-to-store-rsa-key-pair-on-ios-keychain-xamarin

    and if possible give me some tips please?
    Many thanks in advance

    ReplyDelete
  5. This is my first visit to your web journal! We are a group of volunteers and new activities in the same specialty. Website gave us helpful data to work. https://foodkeychains.com/

    ReplyDelete
  6. On the off chance that you have your go to put for repair parts for iPhone 3g handsets previously set to go, it will involve basically squeezing the catch and pausing. Handy reparatur

    ReplyDelete
  7. The world needs no presentation in regards to the contention among iOS and Android advanced cells. While the applications and offices gave by both Android and iOS working frameworks is a great deal not quite the same as one another, yet the world advanced mobile phone client base gets tremendously influenced with each new dispatch from these mammoths. myjio app

    ReplyDelete

Feedback for my Apps.

I realized getting a hold of me directly through the App Store was difficult, so if you have an issue with any of my apps in the App Store, ...