# Мастер-лицензия для iOS

Мастер-лицензия – это оффлайн-лицензия, с которой можно использовать мобильные SDK без ограничений по `bundle_id`, в отличие от обычных лицензий. Для получения мастер-лицензии нужно создать пару ключей, как описано ниже. Отправьте нам публичный ключ по электронной почте, и вскоре после этого мы отправим вам мастер-лицензию.\
Вашему приложению нужно будет подписать свой `bundle_id` приватным ключом. Мобильные SDK проверяют подпись с помощью публичного ключа из мастер-лицензии. Действие таких лицензий ограничено по времени.

## Генерация ключей

В этом разделе описано, как создавать приватный и публичный ключи.

### Создание приватного ключа

Чтобы создать приватный ключ, последовательно запустите следующие команды:

```bash
openssl genpkey -algorithm RSA -outform DER -out privateKey.der -pkeyopt rsa_keygen_bits:2048
# for MacOS
base64 -i privateKey.der -o privateKey.txt
# for Linux 
base64 -w 0 privateKey.der > privateKey.txt
```

Вы получите два файла:

* *privateKey.der* – приватный ключ .der;
* *privateKey.txt* – *privateKey.der* в кодировке *base64*. Содержимое этого файла используется в качестве подписи *bundle\_id* хостового приложения.

Спецификация команд OpenSSL: <https://www.openssl.org/docs/man1.1.1/man1/openssl-pkcs8.html>

{% file src="/files/1T2MTHkL6TRNOevzrZSF" %}

### Создание публичного ключа

Чтобы создать публичный ключ, последовательно запустите следующие команды:

```sh
openssl rsa -pubout -in privateKey.pem -out publicKey.pub
base64 -w 0 publicKey.pub > publicKey.txt
```

Вы получите публичный ключ *publicKey.pub*. Отправьте его нам по электронной почте. В ответ мы пришлем вам лицензию.

{% file src="/files/mqWdnoutJSpy0Ggad15Z" %}

## Интеграция SDK

Инициализация SDK:

```swift
OZSDK(licenseSources: [LicenseSource], masterLicenseSignature: String? = nil, completion: @escaping ((LicenseData?, LicenseError?) -> Void))
```

Установка лицензии:

```swift
setLicense(licenseSource: LicenseSource, masterLicenseSignature: String? = nil)
```

Перед инициализацией SDK создайте закодированную base64 подпись для `bundle_id` хостового приложения с помощью приватного ключа.

Пример создания подписи:

```swift
private func getSignature() -> String? {
    let privateKeyBase64String = "содержимое файла privateKey.txt"
 
    guard let data = Data(base64Encoded: privateKeyBase64String, options: [.ignoreUnknownCharacters]) else {
      return nil
    }
     
    let sizeInBits = data.count * 8
    let keyDict: [CFString: Any] = [
      kSecAttrKeyType: kSecAttrKeyTypeRSA,
      kSecAttrKeyClass: kSecAttrKeyClassPrivate,
      kSecAttrKeySizeInBits: NSNumber(value: sizeInBits)
    ]
     
    var error: Unmanaged<CFError>?
    guard let secKey = SecKeyCreateWithData(data as CFData, keyDict as CFDictionary, &error) else {
      return nil
    }
     
    guard let bundleID = Bundle.main.bundleIdentifier else {
      return nil
    }
    guard let signature = SecKeyCreateSignature(secKey,
                          .rsaSignatureMessagePKCS1v15SHA512,  // Это критично!!!!
                          Data(bundleID.utf8) as CFData,
                          &error) else {
      return nil
    }
    return (signature as Data).base64EncodedString()
  }
```

<details>

<summary>Пример подписи для <code>com.ozforensics.liveness.demo</code></summary>

`NcdfzExUuQcdSxdY3MUVp4rUGnJTfeTGh/EN0hqiDUSadxf9jhaYe3EHmBPb+DafWrpvP6h6ZON3fHZcqqlykpWtVlPNr7ZpchPJXgHSdIOetKjPxYWh8xrt0NUSzm9Mymv1vz7UUdLiPFXDbanAedkg4YOX8uVJjfP8gb+suLdeTE3CHm+fdK5IVMP1SMu0XsBiiWBtVZp15l6tz7fDv+frr5kCr8I/LAHo6pCHBtzsXUiYw6ylrU/PHI1QYuyKK96iTxBt3gU+/MrfHl2DHLief3Fs10m3doJmTPizwWi/8h6fvq+6ZZlV/q4S2uPE3gpQZrZe2u3FuSE8gEgVoA==`

</details>

Передайте подпись как параметр `masterLicenseSignature` во время инициализации SDK или установки лицензии.

Если подпись невалидна, инициализация продолжится по стандартной схеме: проверка включенных в лицензию `bundle_id`.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://doc.ozforensics.com/oz-knowledge-ru/rukovodstva/rukovodstvo-razrabotchika/sdk/oz-mobile-sdk/ios/poluchenie-licenzii/master-licenziya-dlya-ios.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
