Реалізація безпечного зберігання ключів у Secure Enclave (iOS) для криптогаманця

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Реалізація безпечного зберігання ключів у Secure Enclave (iOS) для криптогаманця
Складний
~3-5 днів
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    495

Реалізація безпечного зберігання ключів у Secure Enclave (iOS) для криптокошелька

Secure Enclave — окремий процесор всередину Apple SoC, ізольований від основного CPU та RAM. Приватний ключ, сгенерований у Secure Enclave, фізично не залишає чип — навіть ваш код до нього прямого доступу не має. Операція підписання виконується всередину SE та назовні повертається тільки результат.

Обмеження, які потрібно знати перед стартом

Secure Enclave підтримує тільки P-256 (secp256r1, він же NIST P-256). Це не secp256k1, яку використовують Bitcoin та Ethereum. Тому SE не підходить для прямого зберігання приватних ключів ETH/BTC. Типове використання для крипто-кошелька — зберігати в SE ключ шифрування, яким зашифрований secp256k1 приватний ключ у Keychain. Або використовувати SE для біометричної захисту Keychain-запису через SecAccessControlCreateWithFlags.

Якщо ваше програма працює з блокчейнами, що використовують P-256 (наприклад, деякі enterprise-ланцюги або NEAR протокол через ed25519 — не плутати), SE можна використовувати для прямого зберігання та підписання.

Створення ключа у Secure Enclave

let accessControl = SecAccessControlCreateWithFlags(
    nil,
    kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
    [.privateKeyUsage, .biometryCurrentSet],
    nil
)!

let attributes: [String: Any] = [
    kSecAttrKeyType as String:        kSecAttrKeyTypeECSECPrimeRandom,
    kSecAttrKeySizeInBits as String:  256,
    kSecAttrTokenID as String:        kSecAttrTokenIDSecureEnclave,
    kSecPrivateKeyAttrs as String: [
        kSecAttrIsPermanent as String:    true,
        kSecAttrApplicationLabel as String: "wallet-signing-key-v1",
        kSecAttrAccessControl as String:  accessControl
    ]
]

var error: Unmanaged<CFError>?
guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
    throw error!.takeRetainedValue()
}

kSecAttrTokenIDSecureEnclave — це й є вказівка системі створити ключ у SE. biometryCurrentSet інвалідує ключ при зміні біометрії (додавання нового отпечатка або зміна Face ID). Для кошелька це правильне поведінка — потребує явної переаутентифікації.

Підпис даних через SE-ключ

let publicKey = SecKeyCopyPublicKey(privateKey)!
let algorithm: SecKeyAlgorithm = .ecdsaSignatureMessageX962SHA256

guard SecKeyIsAlgorithmSupported(privateKey, .sign, algorithm) else {
    throw WalletError.algorithmNotSupported
}

var signError: Unmanaged<CFError>?
guard let signature = SecKeyCreateSignature(
    privateKey,
    algorithm,
    dataToSign as CFData,
    &signError
) else {
    throw signError!.takeRetainedValue()
}

Підпис виконується асинхронно з точки зору UI — поки SE обробляє запит (і якщо потрібна біометрія — поки користувач аутентифікується), main thread не блокується. Весь виклик потрібно винести в Task або dispatch queue.

Схема для ETH/BTC кошельків

Раз SE не працює з secp256k1 безпосередньо, використовуємо таку схему:

  1. Генеруємо ephemeral P-256 ключ у SE — це "ключ шифрування"
  2. Генеруємо secp256k1 приватний ключ у пам'яті
  3. Шифруємо secp256k1 ключ через ECIES з публічним ключем SE: SecKeyCreateEncryptedData з алгоритмом eciesEncryptionStandardX963SHA256AESGCM
  4. Зберігаємо зашифрований blob у Keychain з kSecAttrAccessibleWhenUnlockedThisDeviceOnly
  5. При підписанні транзакції: розшифровуємо через SE (що вимагає біометрію), використовуємо secp256k1 ключ для підписання, одразу обнуляємо з пам'яті

Це дороговартісніше за однократне Keychain-зберігання за складністю, але ключ ніколи не живе на диску в откритому вигляді.

Процес

Аудит вимог (P-256 безпосередньо або схема шифрування для secp256k1), реалізація, тестування на реальному залізі — симулятор не підтримується. Окремо тестуємо поведінку при зміні біометрії, при видаленні та переустановці програми.

Часова шкала — 3–5 днів. Симулятор для більшої частини розробки достатній, але кінцеве тестування тільки на пристрої.