KeyChain とは
キーチェーンと呼ばれる暗号化されたデータベースに
下記のユーザーデータの小さなビットを格納するメカニズムです。
・パスワード
・Trust Servicesで管理する暗号化キーと証明書
・秘密メモ
キーチェーンアクセス
パスワードやアカウント情報を保管するmacOSアプリケーション
iOSのUserDefaults
ユーザーのデフォルトデータベースへのインターフェイスです。
・長点: アプリの起動時にキーと値のペアを永続的に保存します。
処理が簡単であること。
・短点: アプリ削除ですべて消えること。
データがそのまま保存するため、安全ではないこと。
構造体はそのまま保存できないため、Dataなどで変換して保存しないといけないこと。
iOSのKeychain
・長点: アプリ削除しても消えないこと。
セキュアな値を保存できること(apple推奨)
・短点: 処理が少し複雑
大量のデータ保存には向いてないこと。
kSecClass
kSecClassGenericPassword: パスワード(通常)
let kSecClassInternetPassword: パスワード(Internet)
let kSecClassCertificate: 証明書?
let kSecClassKey: 暗号鍵(秘密鍵、公開鍵など)
let kSecClassIdentity: 秘密鍵付き証明書
let dic: [String: Any] =
[kSecClass as String: kSecClassGenericPassword,
kSecAttrGeneric as String: key, // 自由項目(グループ)
kSecAttrAccount as String: "account", // アカウント(ログインIDなど)
kSecValueData as String: data] // 保存情報
ユニークキー
検索時にある1つのアイテムを特定するキー(ユニークキー)は kSecClassGenericPassword の場合、
次の2つで構成されている
kSecAttrAccount
kSecAttrService
Keychain 登録/更新
// 保存データが存在するかの確認
let matchingStatus = SecItemCopyMatching(dic as CFDictionary, nil)
switch matchingStatus {
// 保存
case errSecItemNotFound:
SecItemAdd(dic as CFDictionary, nil)
// 更新
case errSecSuccess:
SecItemUpdate(dic as CFDictionary,
[kSecValueData as String: data] as CFDictionary)
default:
debugPrint("キーチェーン保存失敗(\(matchingStatus)")
}
Keychain 取得
var dataTypeRef: AnyObject? = nil
let matchingStatus = withUnsafeMutablePointer(to: &dataTypeRef) {
SecItemCopyMatching(dic as CFDictionary, UnsafeMutablePointer($0))
}
if matchingStatus == errSecSuccess,
let getData = dataTypeRef as? Data {
// キーチェーン取得結果
String(data: getData, encoding: .utf8)
}
テストコード
func testKeychainIfSaveKeychainThenEqualToGetKeychainResult() throws {
guard let data = "testtest".data(using: .utf8) else {
XCTFail()
return
}
let key = "encryptedkey"
let value = SHA256.hash(data: data).hexStr
KeychainAccess.saveKeyChain(key: key, vaule: value)
let result = KeychainAccess.getKeyChain(key: key)
XCTAssertTrue(value == result)
}
課題
・kSecClassKeyなど対応方法は?
kSecClassGenericPassword を kSecClassKey変更した場合、キーチェーンから情報が取得できませんでした。
参照
キーチェーンアクセスユーザガイド
Apple - UserDefaults
KeyChain Services
Apple - Item Class Keys and Values
[iOS] Keychain Services とは