PKCS12, PEM чи DER: що насправді потрібно клієнту VPN
Пакування визначає, чи імпортує ваш клієнт ідентичність, а не чи їй довіряють. Порівняйте PKCS12, PEM і DER, а потім перевірте.
У дискусіях про сертифікати ходять два твердження. Перше — що .p12 є надійним варіантом, а .pem — слабким; друге — що текстовий файл можна безпечно надсилати, бо ви можете його прочитати. Жодне з них не витримує хвилини перевірки.
PKCS12, PEM і DER описують, як пакуваються та кодуються об’єкти сертифікатів. Вони не визначають, хто є протилежною стороною, чи довіряють видавцеві, чи потрібен файлу пароль.
Те, що приймає клієнт, — це питання сумісності. Те, що містить файл, — це питання ідентичності. Тримайте ці речі окремо, і більшість помилок імпорту перестане бути загадкою.
Три контейнери, одна об’єктна модель
Почніть з того, що у вас насправді є. Сертифікат — це підписане твердження про відкритий ключ. Закритий ключ — це окремий матеріал, який доводить, що ви контролюєте цей ключ. Ланцюжок — це набір видавців, що з’єднують ваш сертифікат із коренем, якому довіряє клієнт. Усі три існують незалежно від пакування.
Файл PKCS12, зазвичай .p12 або .pfx, — це контейнер, визначений у RFC 7292, який може нести закритий ключ, один або кілька сертифікатів і ланцюжок в одному захищеному паролем блобі, з псевдонімом, що називає ідентичність. Файл PEM — це текстове обрамлення, визначене в RFC 7468: тіло base64 між рядками BEGIN і END, і один файл може містити кілька блоків послідовно. DER — це двійкове кодування тих самих структур ASN.1, а тіло PEM — це буквально DER, обгорнутий base64.
Останнє речення варто запам’ятати. Перетворення PEM на DER переписує обгортку, а не вміст, а зворотне перетворення повертає початкові байти.
| Container | Can hold | Does not decide |
|---|---|---|
| PKCS12 (.p12, .pfx) | Key, leaf certificate, chain, alias, password | Which root the client trusts |
| PEM (.pem, .crt, .cer) | Any number of base64 blocks | Whether the private key is present |
| DER (.der, .cer) | One binary structure | The object type, whatever the extension says |
Кодування — це не шифрування
Base64 — це транспортний алфавіт. Він нічого не приховує, і будь-хто може декодувати блок PEM у шелі. Файл DER є двійковим і так само публічним. Жодна з цих властивостей не є захистом, і жодна не означає, що пароль існує.
Справжній захист живе в матеріалі ключа. Пакет PKCS12 може шифрувати свій вміст ключем, похідним від пароля. Закритий ключ PEM можна зашифрувати застарілим блоком заголовка або зберігати в PKCS#8 EncryptedPrivateKeyInfo. Сертифікат сам по собі не містить нічого таємного, тому експорт, який видав лише сертифікат, залишає клієнт нездатним автентифікуватися, у який би формат ви його не загорнули.
Розширення — це підказка, а не контракт. Файли з закінченням .cer і .crt трапляються в обох кодуваннях, і пристрої досить часто експортують сертифікати DER під іменами .pem, тож вгадування за суфіксом коштує цілого дня. Натомість прочитайте перші байти: файл PEM відкривається рядком BEGIN, а DER починається з 0x30, бо зовнішня структура — це SEQUENCE.
Чому імпорт насправді не вдається
Повідомлення про помилки клієнта стискають кілька різних проблем в одне речення про недійсний сертифікат, тож розділяйте їх за причиною. Найпоширеніша — невідповідність кодування: клієнт, що розбирає PEM, повертає помилку розбору на файлі DER, і виправленням є перетворення, а не новий сертифікат. Друга — відсутній ключ, коли сертифікат гаразд, але ідентичність довести неможливо. Третя — ланцюжок, коли пакет без проміжного сертифіката виглядає правильно в діалозі імпорту й зазнає невдачі під час рукостискання.
Параметри шифрування спричиняють четверту, і вона виглядає точно як неправильний пароль. Старіші пристрої експортували файли PKCS12 з RC2-40 і 3DES, які OpenSSL 3 відкидає, якщо не завантажено застарілий провайдер. Повторний експорт із пристрою з AES-256-CBC і PBKDF2 — це тривале виправлення. Постійно тримати застарілі шифри ввімкненими на клієнтській машині заради одного файлу — погана оборудка.
П’ята — неоднозначність. Контейнер із двома ключами й двома сертифікатами або файл PEM із трьома блоками CERTIFICATE змушує клієнт обирати, і його вибір часто просто перший елемент. Коли тунель піднімається з неправильною ідентичністю, це зазвичай і є причина.
Огляньте перед перетворенням
Прочитайте структуру, не друкуючи секретів. openssl pkcs12 -in bundle.p12 -info -noout повідомляє алгоритми шифрування та псевдоніми, пригнічуючи вивід ключа й сертифіката, а посібник openssl-pkcs12 документує прапорці. Прибрати -noout і додати -nodes — це для створення файлів, які ви маєте намір зберігати, а не для швидкого погляду, бо це записує закритий ключ у відкритому вигляді.
Для сертифіката openssl x509 -in cert.pem -noout -subject -issuer -dates відповідає на те, на що не відповість діалог імпорту, а додавання -ext subjectAltName показує імена, для яких сертифікат справді дійсний. Якщо файл DER, додайте -inform DER; цей єдиний прапорець вирішує більшість помилок завантаження.
Зіставити ключ із сертифікатом — механічна робота, і її варто зробити перед будь-яким імпортом:
openssl x509 -in cert.pem -noout -pubkey | openssl sha256openssl pkey -in key.pem -pubout | openssl sha256
Однакові дайджести означають, що пара належить одна одній. Різні дайджести означають, що у вас неправильний ключ, і жодне перетворення формату цього не змінить.
Що формат не змінює ніколи
Рішення про довіру ухвалюються над контейнером. Клієнт проходить ланцюжком до кореня у своєму сховищі, перевіряє вікно дійсності, перевіряє розширене використання ключа для автентифікації клієнта, а на боці сервера перевіряє, що ім’я, до якого він звертався, є в сертифікаті. Жоден із цих кроків не читає розширення файлу.
Ось чому перейменування файлу, доки помилка не зникне, — такий надійний спосіб втратити час. Імпорт вдається, ідентичність усе ще неправильна, і збій повертається під час рукостискання, де повідомлення менш корисне. Ось чому пакет, експортований два роки тому, чисто імпортується і все одно відхиляється: дата закінчення подорожувала всередині сертифіката, а не в імені файлу.
Порядок, що уникає переробки
Запитайте в документації клієнта, які кодування він приймає і який контейнер очікує для ідентичності клієнта, а потім подивіться, що вам дали. Якщо клієнту потрібна одна імпортована ідентичність, а у вас окремі файли PEM, зберіть пакет один раз із паролем, який ви контролюєте, і збережіть джерела. Якщо йому потрібен PEM, видобудьте ключ і ланцюжок, а потім видаліть проміжні файли через той процес обробки облікових даних, який ваша команда вже використовує.
Після імпорту перевіряйте ідентичність, а не діалог: суб’єкт, видавець, термін дії та ім’я, яке представить клієнт. Дружнє ім’я в списку — це мітка, а не підтверджена ідентичність. Якщо тунель потім не працює, ви налагоджуєте автентифікацію або маршрутизацію, а не пакування, і це набагато коротша розмова.