# Клиентский SSL-сертификат в macOS: Safari, Chrome, Firefox


<!--more-->

Эта инструкция -- продолжение статьи
[Настройка аутентификации по SSL сертификатам клиентов на Nginx]({{< relref "client-certificate-authentication-nginx" >}}).
У вас есть файл `user1.p12` с сертификатом и закрытым ключом и пароль от него. Осталось установить его в систему.

В macOS клиентские сертификаты хранятся в **Связке ключей** (Keychain), и ее используют все основные браузеры:

- **Safari, Chrome, Яндекс Браузер, Edge, Opera, Brave** -- берут сертификаты из связки ключей;
- **Firefox** начиная с версии 90 тоже видит сертификаты из связки ключей, а кроме того имеет собственное хранилище.

Поэтому достаточно один раз установить сертификат в связку ключей **вход** (login), и он будет доступен всем браузерам.

{{< admonition type=warning open=true >}}
**macOS 14 и более ранние версии не принимают `.p12` из OpenSSL 3 с настройками по умолчанию.** OpenSSL 3 шифрует контейнер
алгоритмами AES-256 и PBKDF2, которые система научилась читать только в macOS 15. Старые версии отвечают ошибкой
неверного пароля, даже если пароль правильный. Пересоздайте файл с параметром `-legacy`:

```shell
openssl pkcs12 -export -legacy -in user1.crt -inkey user1.key -out user1.p12
```
{{< /admonition >}}


## Установка через интерфейс

1. Дважды щелкните по файлу `user1.p12`. Откроется приложение **Связка ключей** (Keychain Access).
   Если этого не произошло, откройте его через Spotlight (**Cmd + Пробел → Связка ключей**) и выберите
   **Файл → Импортировать объекты...**
2. В качестве связки ключей выберите **вход** (login) и нажмите **Добавить**.
3. Введите пароль от файла `.p12`.
4. Сертификат появится в разделе **Мои сертификаты**. Раскройте его -- под ним должен быть закрытый ключ.

При первом заходе на сайт браузер предложит выбрать сертификат, а macOS спросит, разрешить ли приложению использовать
закрытый ключ: «*Браузер* хочет подписать данные с помощью ключа ... в Вашей связке ключей». Введите пароль от
учетной записи и нажмите **Разрешать всегда**, чтобы вопрос не повторялся.

Удалить сертификат можно там же: в **Мои сертификаты** правой кнопкой по сертификату → **Удалить**. Закрытый ключ
удалится вместе с ним.


## Установка через консоль

Для работы со связкой ключей в macOS есть встроенная утилита `security`. Импорт в связку **вход**:

```shell
security import user1.p12 -k ~/Library/Keychains/login.keychain-db
```

Утилита спросит пароль от файла в отдельном окне. Для скриптов пароль можно передать параметром `-P`, а чтобы не
оставлять его в истории команд, -- прочитать заранее:

```shell
read -s P12PASS
security import user1.p12 -k ~/Library/Keychains/login.keychain-db -P "$P12PASS" \
    -T "/Applications/Safari.app" -T "/Applications/Google Chrome.app"
unset P12PASS
```

Параметры `-T` сразу разрешают указанным приложениям использовать закрытый ключ, и macOS не будет спрашивать
разрешение при первом заходе на сайт. Без них появится вопрос, описанный выше.

Посмотреть установленные клиентские сертификаты (вместе с закрытыми ключами):

```shell
security find-identity -v -p ssl-client
```

Удалить сертификат вместе с закрытым ключом. Подставьте **Common Name** сертификата или его SHA-1 хеш из вывода
предыдущей команды:

```shell
security delete-identity -c "user1"
```

### Сертификат по умолчанию для сайта

Если в связке ключей несколько клиентских сертификатов, можно указать, какой использовать для конкретного сайта.
Safari тогда не будет спрашивать о выборе:

```shell
security set-identity-preference -c "user1" -s "https://example.com/"
```


## Firefox

Начиная с версии 90 Firefox автоматически использует сертификаты из связки ключей. Если вы установили сертификат
способами выше, больше ничего делать не нужно -- при заходе на сайт Firefox предложит его выбрать.

Если Firefox не видит сертификат, откройте `about:config` и проверьте, что параметр
`security.osclientcerts.autoload` равен `true`.

Можно установить сертификат только в Firefox, не трогая систему: **Настройки → Приватность и Защита → Сертификаты →
Просмотр сертификатов... → Ваши сертификаты → Импортировать...** Так сертификат будет доступен только в этом профиле
Firefox. Ограничение на `-legacy` здесь не действует -- Firefox читает современные `.p12` в любой версии macOS.


## Если сертификат не работает

- **«Неверный пароль» при импорте.** Если пароль правильный, а версия macOS ниже 15, -- пересоздайте `.p12` с
  параметром `-legacy` (см. выше).
- **Браузер не предлагает выбрать сертификат.** Проверьте в **Связке ключей**, что сертификат лежит в связке **вход**,
  в разделе **Мои сертификаты**, и под ним есть закрытый ключ. Если сертификат попал в **Сертификаты** без ключа --
  удалите его и импортируйте `.p12` заново.
- **Выбран не тот сертификат.** Chrome запоминает выбор до перезапуска -- закройте его через **Cmd + Q**. Для Safari
  проверьте настройку сертификата по умолчанию: в **Связке ключей** она отображается как запись с адресом сайта.
- **Сервер отклоняет сертификат.** Проверьте, что он подписан тем центром сертификации, который указан в
  `ssl_client_certificate` в настройках nginx, и что у CA и клиента разные поля **Organization Name**.

Инструкции для других систем:
[Windows]({{< relref "client-certificate-windows" >}}),
[Linux]({{< relref "client-certificate-linux" >}}),
[Android и iOS]({{< relref "client-certificate-android-ios" >}}).

