# Мастер-лицензия для 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="broken-reference" %}

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

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

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

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

{% file src="broken-reference" %}

## Интеграция 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`.
