19
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

iOSのKeyChainについてゆるふわにまとめる

Last updated at Posted at 2016-08-04

KeyChainとは

ざっくり書くと

  • 機密情報を安全に取り扱う仕組み
  • パスワードや秘密鍵・公開鍵などの機密情報を安全に管理するための仕組み

また、KeyChainで管理する情報は暗号化されているとのこと
ユーザの情報を保存する仕組みとして UserDefaults がありますが、これは設定ファイルなどのプリファレンス情報を管理するための仕組み。

UserDefaultsとの違い

  • アプリが削除されてもデータが残る
  • 同じKeychain Access Groupに属するアプリ同士でアクセスできる
  • データが暗号化される

準備

プロジェクト作成

スクリーンショット 2016-08-04 午前10.05.27.png

Frameworkの追加

スクリーンショット 2016-08-04 午前10.13.17.png

Linked Frameworks and Libraries から Security.framework を追加する。

ライブラリインストール

今回はKeyChainの便利なライブラリを使用します。

TheLevelUp/LUKeychainAccess

Podfile
pod 'LUKeychainAccess', '~> 1.2'
$ pod install
$ open PROJECT_NAME.xcworkspace/

KeyChain準備

スクリーンショット_2016-08-04_午前10_20_37.png

スクリーンショット_2016-08-04_午前10_20_32.png

KeyChain Groupは私の場合は moe.nnsnodnb.* のアプリ間で連携することができます。
GoogleさんがリリースされているアプリはこのKeyChain Groupを使って初めてのログイン以降は自動的にログインができるようになっているのではないでしょうか?

準備はとりあえず完了!!

アクセス制御

KeyChainはアプリを削除してもデータが残っているということでアクセス制御が Accessible属性 として存在しています。
今回は LUKeychainAccess に実装されている Accessible属性 について

Accessible属性 概要
LUKeychainAccessAttrAccessibleAfterFirstUnlock 再起動後最初のアンロック以降/次の再起動まで
LUKeychainAccessAttrAccessibleAfterFirstUnlockThisDeviceOnly 再起動後最初のアンロック以降/次の再起動まで
LUKeychainAccessAttrAccessibleAlways 常にアクセス可
LUKeychainAccessAttrAccessibleAlwaysThisDeviceOnly 常にアクセス可
LUKeychainAccessAttrAccessibleWhenUnlocked デバイスがアンロックされた状態
LUKeychainAccessAttrAccessibleWhenUnlockedThisDeviceOnly デバイスがアンロックされた状態

というような感じ

注意

  • シミュレータによるビルドはシミュレータによるグループの取り扱いがすべて test となってしまうので実機でのビルドをすること
  • Debug用ビルドやAdHoc用ビルドなどでは、 Code Signing Identity が異なるためKeyChainアクセスがアプリ間では行えません

ソースコード

今回はボタンを押すと「 小泉花陽ちゃん 」という文字が出力されるようなものを作成しました。

ViewController.m
#import "ViewController.h"
#import <LUKeychainAccess/LUKeychainAccess.h>

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UILabel *label;
- (IBAction)callKeyChain:(id)sender;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    LUKeychainAccess *keychainAccess = [LUKeychainAccess standardKeychainAccess];
    keychainAccess.accessibilityState = LUKeychainAccessAttrAccessibleWhenUnlocked;
    [[LUKeychainAccess standardKeychainAccess] setString:@"小泉花陽ちゃん" forKey:@"rice"];
    self.label.hidden = YES;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (IBAction)callKeyChain:(id)sender {
    self.label.hidden = NO;
    self.label.text = [[LUKeychainAccess standardKeychainAccess] stringForKey:@"rice"];
}

@end

実行サンプル

Simulator Screen Shot 2016.08.04 午前10.49.21.png

Simulator Screen Shot 2016.08.04 午前10.49.23.png

いろんな型をKeyChainに管理させる

TestKeyChain.m
#import <XCTest/XCTest.h>
#import <LUKeychainAccess/LUKeychainAccess.h>

@interface sample_keychainTests : XCTestCase

@end

@implementation sample_keychainTests

- (void)setUp {
    [super setUp];
    // integer
    [[LUKeychainAccess standardKeychainAccess] setInteger:1 forKey:@"integerKey"];
    // float
    [[LUKeychainAccess standardKeychainAccess] setFloat:1.0 forKey:@"floatKey"];
    // double
    [[LUKeychainAccess standardKeychainAccess] setDouble:1.0 forKey:@"doubleKey"];
    // BOOL
    [[LUKeychainAccess standardKeychainAccess] setBool:YES forKey:@"boolKey"];
    // NSString
    [[LUKeychainAccess standardKeychainAccess] setString:@"string" forKey:@"stringKey"];
    // NSObject
    [[LUKeychainAccess standardKeychainAccess] setObject:@"object" forKey:@"objectKey"];
}

- (void)tearDown {
    [super tearDown];
}

- (void)testKeyChain {
    XCTAssertEqual([[LUKeychainAccess standardKeychainAccess] integerForKey:@"integerKey"], 1);
    XCTAssertEqual([[LUKeychainAccess standardKeychainAccess] floatForKey:@"floatKey"], 1.0);
    XCTAssertEqual([[LUKeychainAccess standardKeychainAccess] doubleForKey:@"doubleKey"], 1.0);
    XCTAssertEqual([[LUKeychainAccess standardKeychainAccess] boolForKey:@"boolKey"], YES);
    XCTAssertEqualObjects([[LUKeychainAccess standardKeychainAccess] stringForKey:@"stringKey"], @"string");
    XCTAssertEqualObjects([[LUKeychainAccess standardKeychainAccess] objectForKey:@"objectKey"], @"object");
}

@end

参考

19
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?