Как подписать профиль конфигурации iOS, сгенерированный программно?
контекст
У меня есть веб-приложение (внешний JS / backend PHP), которое генерирует некоторые профили конфигурации MDM iOS (*.mobileconfig) программно.
Пользователи веб-сайта вводят некоторую информацию, называют мой PHP API, а мой PHP-сервер генерирует профиль конфигурации "на лету" с пользовательскими данными, сохраняет их на сервере и возвращает URL-адрес сгенерированного профиля, поэтому пользователь может щелкнуть эту ссылку и установить ее на своем устройстве iOS.
Вкратце: этот профиль содержит в своем материале только веб-клип (ярлык safari).
Все работает нормально, ссылка на профиль конфигурации открывает приложение iOS Settings, которое просит пользователя установить этот профиль на свое устройство.
Моя проблема в том, что этот программно созданный профиль не подписан. Поэтому iOS предупреждает пользователя о том, что профиль не подписан, и он должен выполнить несколько дополнительных действий для подтверждения установки профиля.
Мне бы хотелось, чтобы сгенерированные профили были подписаны, чтобы пользователь мог установить их проще и быстрее.
Вопросы
- Является ли это возможным?
- если да, возможно ли это с помощью PHP?
- если да, как я могу это сделать?
Я читал некоторые материалы о подписании профилей конфигурации, поскольку я не все понимаю, у меня нет навыков подписи, сертификатов и т. Д.
Это не ясно для меня!
Любая помощь приветствуется, спасибо заранее!
1 ответ
Я могу подтвердить, что это работает, используя ответ zvi. Спасибо!
Позвольте мне рассказать подробнее о моей реализации, чтобы помочь другим людям. Особенно меня смутило, какие файлы мне нужно подписать и как их получить.
1. Получить сертификат
Я использовал бесплатный сертификат Let's Encrypt через ZeroSSL, чтобы легко получить 2 необходимых файла (сертификат и закрытый ключ).
Вам нужно будет доказать, что домен принадлежит вам (используя метод FTP или DNS)
Я сохранил сертификат как "certificate.crt" и закрытый ключ как "private-key.pem". Загрузите их где-нибудь на свой сервер.
2. Получить файл цепочки сертификатов
Если вы просто используете 2 файла выше, ваш профиль будет подписан, но не "проверен" в iOS (зеленый флажок, который я искал)
Загрузите "Сеть доверия" с этой страницы.
Я использовал "Let's Encrypt Authority X3 (IdenTrust cross -signature)" и сохранил его в "ca-chain.pem". Загрузите его на свой сервер вместе с двумя другими.
3. Сделайте метод входа в PHP
Чтобы подписать его через PHP-скрипт, я создал для этого метод, взяв файл входного профиля (не подписанный) и записав его в файл выходного профиля (подписанный).
Я использовал описанный здесь метод для вызова команды openssl из PHP с использованием shell_exec
<?php
function sslSignProfileToFile($inputFile, $outputFile)
{
$sslPath = '/absolute/path/to/your/cert/files';
shell_exec("openssl smime -sign -signer ".$sslPath."/certificate.crt -inkey ".$sslPath."/private-key.pem -certfile ".$sslPath."/ca-chain.pem -nodetach -outform der -in ".$inputFile." -out ".$outputFile);
}
?>
4. Создайте свой профиль и подпишите его
Создайте его, как вам нужно, и затем вызовите метод выше, чтобы сделать его копию с подписью.
<?php
sslSignProfileToFile( "/path/to/your/unsigned-profile.mobileconfig", "/path/to/your/signed-profile.mobileconfig");
?>
5. НАСЛАЖДАЙТЕСЬ!
Тогда вам решать:
если вы в AJAX-запросе, как я, вы можете вернуть обратно в теле URL-адрес подписанного профиля для загрузки
если вы использовали POST-действие классической формы, вы можете просто выполнить перенаправление заголовка, как описано здесь (не проверено мной)
Да, ты можешь. Также с PHP.
Как?
Сохраните профиль, который хотите подписать, во временный файл:
file_put_contents ($ tmp_file_name, $ profile_data);
Подпишите файл, который вы только что создали:
$ data = shell_exec ("openssl smime -sign -in $ tmp_file_name {добавьте сюда другие параметры, которые вам нужны...}");
Отправьте данные клиенту:
echo $ data;
Удалить файл tmp...
unlink ($ tmp_file_name);
Если только для проблемы со знаком, я уже ответил на один раньше, см. /questions/35293014/podpishitemobileconfig-na-servere-php/55190616#55190616
/**
* Sign MobileConfig
*
* @return string
*/
function signMobileConfig (
string $file_full_pathname,
string $certificate_pathname,
string $private_key_pathname,
bool $remove_file = true
) {
openssl_pkcs7_sign(
$file_full_pathname,
$file_full_pathname.'.sig',
file_get_contents($certificate_pathname),
file_get_contents($private_key_pathname),
[], 0
);
$signed = file_get_contents($file_full_pathname.'.sig');
if ($remove_file) {
unlink($file_full_pathname.'.sig');
unlink($file_full_pathname);
}
$trimmed = preg_replace('/(.+\n)+\n/', '', $signed, 1);
return base64_decode($trimmed);
}
результат подписанного файла конфигурации (репутация <10, поэтому нажмите, чтобы увидеть результат)
Не стесняйтесь изменять приведенный выше код в соответствии со своими требованиями.