PKCS12
PKCS #12 | |
---|---|
Последний выпуск |
PKCS #12 v1.0 (24 июня 1999 Technical Corrigendum 1 / 25 февраля 2000 ) |
Тип формата | Архив |
Содержит | X.509 public key certificates, X.509 private keys, X.509 CRLs, generic data |
Расширен из | Microsoft PFX формат файла |
В криптографии PKCS#12 — один из стандартов семейства Public-Key Cryptography Standards (PKCS), опубликованных RSA Laboratories. Он определяет формат файла, используемый для хранения и/или транспортировки закрытого ключа (en:Private key), цепочки доверия от сертификата пользователя до корневого сертификата удостоверяющего центра и списка отзыва сертификатов (CRL). Защита файла осуществляется одним из двух способов: безопасным, с использованием доверенной ключевой пары (открытый/закрытый ключи, подходящие для цифровой подписи и шифрования) или менее безопасным, с использованием симметричного ключа, основанного на пароле. Второй подходит для случаев, когда использование доверенных пар открытый/закрытый ключей недоступны. Формат PKCS#12 — это формат, предназначенный для хранения ключевой пары (закрытый ключ и сертификат), который распознаётся и используется многими браузерами и почтовыми агентами. В файлах PKCS#12 хранятся одновременно и сертификат, и закрытый ключ (разумеется в зашифрованном виде). Примерная организация PKCS#12 файла показана на рисунке справа.
![](https://cdn.xn--h1ajim.xn--p1ai/thumb.php?f=Pkcs12.jpg&width=320)
В этом стандарте описывается синтаксис передачи персональной идентификационной информации, включающей закрытые ключи, сертификаты, различные секреты и многое другое. Этот стандарт поддерживает прямую передачу данных между платформой отправителем и платформой получателем. Стандарт поддерживает передачу данных как с высоким уровнем защиты (с помощью пары открытого/закрытого ключа, используемого для цифровой подписи и шифрования), так и с более низким уровнем защиты (с помощью авторизации по паролю), в том случае, если использование открытого/закрытого ключа недоступно.
Стандарт реализован как аппаратно, так и программно. Пример аппаратной реализации — защищённые опознавательные знаки, такие как Смарт-карта и PC Card.
Этот стандарт может быть рассмотрен как надстройка над стандартом PKCS8. Включена дополнительная идентификационная информация, включающая закрытые ключи. Введён режим высокой безопасности с помощью сокрытия открытого ключа.
Введение
Ещё несколько лет назад криптографические системы применялись лишь в исключительных случаях: в правительственных организациях, спецслужбах и иных критических к безопасности данных системах. Однако в настоящее время бурное развитие компьютерных сетей и Интернета заставляет задумываться об обеспечении безопасности всё большее количество людей. В настоящее время все озабочены безопасностью передаваемых по сети данных. В результате чего появилось множество различных сертификатов, методов шифрования. В данной статье будет рассмотрен формат хранения ключей PKCS#12 и некоторые проблемы, связанные с безопасным хранением закрытых ключей сертификатов.
В течение многих лет большое количество форматов хранения создавалось в дополнение оригинальным форматам PKCS5 и PKCS8, которые были ограничены в использовании DES и MD5. Это привело к распространению несовместимых и зачастую небезопасных форматов хранения закрытого ключа. Вершиной этого стал чрезвычайно сложный формат PKCS12 с его смешением несовместимых идентификаторов объектов, алгоритмов, содержания данных и требований к обработке. В результате этого смешения реализация была и небезопасна и несовместима со старыми версиями. Так как требования не обеспечивали достаточно информации, для реализации совместимых версий. Другая проблема этого формата — раздутие данных, что делало его бесполезным для использования в устройствах с ограниченным количеством памяти, таких как смарт карты.
Эти изменения выдвинули на первый план необходимость упрощения, безопасности и совместимости форматов хранения закрытых ключей. Задачи разработчиков для этого формата заключались в следующем:
- Хранить закрытые ключи в безопасности.
- Использовать как можно меньше новых, не протестированных алгоритмов и методов.
- Убедиться, что относительно легко производить совместимые реализации и относительно сложно изготовить небезопасную реализацию.
- Открыть для компактного кодирования. Для появления возможности использования в носителях ключа, с ограниченным пространством, таких как смарт карты.
- Пусть он будет простым. Формат должен быть разработан для хранения одного закрытого ключа безопасности, чтобы успешная атака на ключевой контейнер не ставила под угрозу целый ряд других данных. С другой стороны успешная атака на PKCS#12 ставит под угрозу более или менее уязвимые куски информации, хранимой пользователем, потому что вся она хранится в одном файле.
Связь с форматом PFX
PKCS # 12 является преемником «PFX» от Microsoft. Термины «PKCS # 12 файл» и «PFX файл» иногда используются как синонимы.
PFX получил тяжёлую критику, является одним из самых сложных криптографических протоколов, но тем не менее остаётся единственным стандартным способом сегодня для хранения закрытых ключей и сертификатов в одном зашифрованном файле.
Netscape использовал формат PFX, а не PKCS#12 в версиях 4.03 и ниже, потому что формат PKCS#12 просто не существовал. Из-за необходимости обратной совместимости Netscape 4.04 и более новые версии, а также все версии MSIE поддерживали только импорт в формат PFX. Приведённая ниже таблица объединяет вышесказанное.
Программное обеспечение | PKCS#12 импорт | PKCS#12 экспорт | PFX импорт | PFX экспорт |
---|---|---|---|---|
Netscape 4.03 и более ранние версии | Да. | Да. | Да. | Да. |
Netscape 4.04 и более поздние версии | Да. | Да. | Да. | Да. |
MSIE 4.0 и более поздние версии | Да. | Да. | Да. | Да. |
SD
Режимы обмена информацией
Любые комбинации режимов конфиденциальности и честности допускаются в этом стандарте. Конечно, хорошая политика безопасности предполагает избежание определённых практик. Например, было бы глупо передавать закрытый ключ без какой-либо физической защиты.
Для обоих режимов (конфиденциальности и честности) предпочтительнее использовать открытый ключ, а не пароль. Однако не всегда предоставляется возможность пользоваться режимом с использованием открытого ключа. Например, если во время отправки мы не знаем достаточно сведений о платформе получателе. В этом случае режим с использованием открытого ключа будет только мешать.
Режим конфиденциальности
- С использованием открытого ключа
Информация шифруется с помощью открытого ключа платформы получателя, шифр открыт вместе с соответствующим ключом. Закрытый ключ находится на платформе получателя и используется для просмотра конфиденциальных данных, содержащихся в сообщении. Пересылка открытого ключа при этом называется TPDestEncK. - С использованием пароля
Информация шифруется симметричным ключом, получаемым из имени пользователя и его пароля, так же как и в стандарте PKCS5.
Режим честности
- С использованием открытого ключа
Честность обеспечивается с помощью ЭЦП, получаемой использованием закрытого ключа платформы источника. Проверка производится путём использования на платформе получателе открытого ключа. Закрытый ключ находится на платформе источнике и используется до подписи персональной информации. Пересылка открытого ключа при этом называется TPSrcSigK. - С использованием пароля
Честность гарантируется с помощью имитовставки, получаемой из пароля. При использовании обоих: режима честности с паролем и режима конфиденциальности с паролем, пароли могут как совпадать, так и не совпадать.
Формат контейнера ключей
Пара закрытого/открытого ключа состоит из двух наборов параметров. Открытые параметры с дополнительной идентификационной информацией, такой как имена пользователей и e-mail адреса, хранятся не зашифрованными. Закрытые параметры в основном хранятся с использованием некоторого механизма защиты, такого как шифрование.
Формат контейнера был определён на основе формата, реализованного в PKCS#7 и S/MIME. Следующий идентификатор объекта идентифицирует безопасный тип хранения содержимого закрытого ключа.
id-securedPrivateKey OBJECT IDENTIFIER ::= { iso(1) org(3) dod(6) internet(1) private(4) enterprise(1) dds(3029) cryptlib(32) 42 }
Безопасный тип хранения содержимого закрытого ключа должен иметь ASN.1 SecuredPrivateKey тип:
SecuredPrivateKey ::= SEQUENCE { version Version, publicKey PublicKeyInfo, privateKey ContentInfo }
Поля типа SecuredPrivateKey имеют следующие значения:
version — номер версии синтаксиса, должен быть равен 0.
publicKey — открытая компонента ключа и дополнительная идентификационная информация о владельце ключа.
privateKey — защищённый закрытый ключ, состоящий из идентификатора типа содержимого и самого содержимого.
Компоненты открытого ключа
Компоненты открытого ключа хранятся в незашифрованной форме. Сделано так, потому что нет достаточно веских причин для шифрования этих данных. Так как шифрование этих данных любым поточным шифром предоставляет атакующему значительно количество известного зашифрованного текста и, потому что должна быть возможность для пользователя получить доступ к его открытому ключу без запроса пароля. Информация об открытом ключе представлена в типе PublicKeyInfo:
PublicKeyInfo ::= CHOICE { publicKeyInfo SubjectPublicKeyInfo, -- Raw public key info certRequest [ 0 ] EXPLICIT PKCS10CertRequest, -- PKCS #10 cert.req. certificate [ 1 ] EXPLICIT Certificate, -- X.509 certificate certChain [ 2 ] EXPLICIT PKCS7CertChain—PKCS #7 cert.chain }
В этой простейшей форме открытый ключ хранится как SubjectPublicKeyInfo. Однажды, когда был сгенерирован запрос сертификации, 'сырая' информация о открытом ключе может быть заменена в соответствии с требованием и, когда ключ сертифицирован, или сертификат или, полный шифр сертификата может быть сохранён.
Компоненты закрытого ключа
Компоненты закрытого ключа могут храниться как в зашифрованной так и не в зашифрованной форме. Зашифрованная форма рекомендуется пока данные не защищены другими средствами. Если данные хранятся в не зашифрованной форме, используется тип содержимого Data. Если же данные хранятся в зашифрованной форме, то используется тип EncryptedData с contentEncryptionAlgorithm — алгоритм шифрования, режим и дополнительные параметры, которые используются при генерации ключа. Содержимое или зашифрованное содержимое полей закрытого ключа (без соответствующих полей открытого ключа), который соответствуют полям открытого ключа, приведённым в PublicKeyInfo.
Например, для RSA:
RSAPrivateKey ::= SEQUENCE { privateExponent INTEGER, -- Private exponent d prime1 INTEGER, -- Prime factor p of n prime2 INTEGER, -- Prime factor q of n exponent1 INTEGER, -- d mod (p-1) exponent2 INTEGER, -- d mod (q-1) coefficient INTEGER—CRT coefficient (q^-1) mod p }
Для DSA и схемы Эль-Гамаля:
DSAPrivateKey ::= SEQUENCE { x INTEGER—Private random integer }
Причины, по которым хранятся только поля закрытого ключа заключаются в следующем: во-первых, для того чтобы избежать избыточности (всё остальное уже содержится в PublicKeyInfo); во-вторых, для того чтобы устранить возможность тривиального восстановления значимой суммы потока ключей, использую известные открытые поля в начале ключа.
Поддерживаемые алгоритмы шифрования
PKCS#12 поддерживает следующие алгоритмы шифрования:
- 128 битный RC4 с SHA1
- 40 битный RC4 с SHA1
- 3 ключевой 3DES с SHA1 (168 бит)
- 2 ключевой 3DES с SHA1 (112 бит)
- 128 битный RC2 с SHA1
- 40 битный RC2 с SHA1
Кроме того также поддерживается режим PKCS#5 v1.5. Это позволяет пользоваться следующими алгоритмами:
Использование PKCS#5 v2.0 позволит использовать произвольный алгоритм шифрования.
OpenSSL может обрабатывать PKCS#5 v1.5 и v2.0 в файлах PKCS#12, однако другие реализации не поддерживаются.
В следующей таблице собраны данные о поддержки различного шифрования:
Программное обеспечение и режим. | Шифрование сертификата | Шифрование закрытого ключа |
---|---|---|
MSIE4 (domestic and export versions) PKCS#12 экспорт. | 40 битный RC2. | 40 битный RC2. |
MSIE4, 5 (domestic and export versions) PKCS#12 импорт. | 40 битный RC2, 3 ключевой 3DES. | 40 битный RC2, 3 ключевой3DES. |
MSIE5 PKCS#12 экспорт. | 40 битный RC2 | 3 ключевой 3DES с SHA1 (168 бит) |
Netscape Communicator (domestic and export versions) PKCS#12 экспорт | 40 битный RC2 | 3 ключевой 3DES с SHA1 (168 бит) |
Netscape Communicator (export version) PKCS#12 импорт. | Только 40 битный шифр. | Все. |
Netscape Communicator (domestic or fortified version) PKCS#12 импорт. | Все. | Все. |
OpenSSL PKCS#12 код. | Все. | Все. |
По умолчанию сильнейшее шифрование поддерживается всеми реализациями приложений, использующих PKCS#12: 3DES для закрытых ключей и RC2-40 для сертификатов. Также дополнительный опции позволяют шифровать сертификат с помощью 3DES.
Следует отметить, что в то время как множественные версии Netscape будут импортировать файлы с помощью разных алгоритмов, тогда как MSIE, кажется, поддерживает только RC2 и 3DES.
Обработка пароля пользователя
Существует несколько механизмов, позволяющий трансформировать пароль пользователя в ключ шифрования. Спецификация PKCS#5 ограничивается итерациями MD2 и MD5 для использования с ключами DES.
Для того, чтобы создать или преобразовать сертификат, вам необходимо программное обеспечение OpenSSL. SSL v3 функция, определена следующим образом:
key = MD5(password + SHA1(“A” + password + salt)) + MD5(password + SHA1(“BB” + password + salt)) + MD5(password + SHA1(“CCC” + password + salt)) + ...
страдает от того, что вход используемый для шага SHA-1 варьируется только несколькими битами входа, используемого на предыдущем шаге и от того, что это требует использования двух различных и фиксированных функций для преобразования пароля в ключ. В дополнение, определённая таким образом функция не позволяет итерируемую обработку необходимую для предотвращения перебора по словарю.
TLS функция расширяет SSL v3 функцию и определяется следующим образом:
key = HMAC(password, A(1) + salt) + HMAC(password, A(2) + salt) + ...
где A(0) = salt — произвольное число, A(1) = HMAC(password, A(0)), …
(как факт: ключ — это XOR, применённый через HMAC-MD5 и HMAC-SHA1, опять требуются два различных фиксированных алгоритма). Другой недостаток использования HMAC заключается в ограничении размера пароля — 64 ASCII символа или 32, или даже 16 для более широкого набора символов, из-за требования сокращения длины ключей, путём хеширования их. Так же, как и в функции SSL v3 нет обеспечения итерируемости функции, для предотвращения перебора по словарю.
Функция получения ключа X.9-42 определена специально в терминах SHA-1:
key = SHA1(password + 1) + SHA1(password + 2) + ...
Это, наверное, худшая из всех функция получения ключа, использующая фиксированную хеш-функцию, изменяющая только единственный входной бит для каждого блока ключа, вводящая крошечное количество изменённых данных после установления пароля, а не до этого и не итерируемый.
Эти предположения выдвигают следующие требования для обработки пароля пользователя:
- Процесс должен быть не зависим от лежащей в основе хеш-функции. И не должен полагаться на доступность множества хеш-функций.
- Должен быть итерируемым, чтобы победить перебор по словарю.
- При использовании повторяющейся хеш-функции, входные данные должны изменяться, для как можно более успешных итераций для предотвращения related-key/input attack.
Другая полезная цель разработки заключается в том, чтобы сделать выход зависимым от алгоритма шифрования; ключ генерируется так, для того чтобы сделать key-recovery attack невозможными. Если тот же самый ключ используется для нескольких алгоритмов, то атакующий, который может получить ключ для одного алгоритма, может воспользоваться этой атакой во время использования других алгоритмов (например, получение ключа DES позволяет получить примерно половину ключа IDEA). Сделав результат шага обработки ключа, зависимым от алгоритма шифрования, режима и конфигурации, значит, что ключ, получаемый из того же самого пароля при помощи использования другого алгоритма режима или конфигурации не просто будет получить.
Эти требования предлагают следующий основной дизайн:
key[] = { 0 }; state = hash( algorithm, mode, parameters, salt, password ); for count = 1 to iterations for length = 1 to keyLength state = hash( state ); key[ length ] ^= hash( state, password );
Внутреннее состояние зависит от всех входных параметров (алгоритма шифрования, режима, параметров, случайного числа salt и, разумеется, пароля). Затем на каждом шаге обработки переменные состояния действуют как генератор псевдослучайных чисел, который гарантирует, что входные параметры хеш-функции, используемой при генерации ключа, изменяются на количество бит, равное выходу хеш-функции на каждом шаге, и гарантирует, что процесс получения пользователем ключа линеен, то есть любая форма параллелизации или предварительных вычислений невозможна. В конечно счёте, при помощи применения XOR для выхода успешного шага обработки и ключа на каждой итерации даёт свой вклад в получаемый ключ.
Параметры обработки пароля
Входные параметры для хеш-функции, используемые для генерации переменных состояния:
StateHashData ::= SEQUENCE { encryptionAlgorithm AlgorithmIdentifier, salt OCTET STRING SIZE(8) OPTIONAL, password UTF8String }
Поля типа StateHashData имеют следующие значения:
encryptionAlgorithm — алгоритм шифрования, режим и дополнительные параметры, которые нужны для генерации ключа. Реализация должна поддерживать 3DES-CBC.
salt — 64-битное случайное число. Этим значением можно пренебречь, если необходимо получить ключ, который постоянен для данного пароля.
password — пароль пользователя, представленной строкой UTF8.
Входные параметры хеш-функции, используемой для получения ключа:
KeyHashData ::= SEQUENCE { state OCTET STRING, password UTF8String }
state — выход хеш-функции, основанной на генераторе случайных чисел.
password — пароль пользователя, представленной строкой UTF8.
Идентификатор алгоритма обработки пароля
Когда используется тип EncryptedData, тогда содержимое contentEncryptionAlgorithm идентифицируется следующим образом:
id-passwordBasedEncryption OBJECT IDENTIFIER ::= { iso(1) org(3) dod(6) internet(1) private(4) enterprise(1) dds(3029) cryptlib(32) 43}
Соответствующие параметры:
PBEParameters ::= SEQUENCE { hashAlgorithm AlgorithmIdentifier, encryptionAlgorithm AlgorithmIdentifier, salt OCTET STRING SIZE(8), iterationCount INTEGER (200...MAX_ITERATION) }
Поля типа PBEParameters имеют следующие значения:
hashAlgorithm — хеш-алгоритм, использующийся для обработки пароля. Реализация должна поддерживать SHA-1 и желательно поддерживать MD5 и RIPEMD-160.
encryptionAlgorithm — алгоритм, использующийся для генерации ключа и для шифрования данных. Имеет то же значение, что и в StateHashData.
slat — имеет то же значение, что и в StateHashData.
iterationCount — количество производимых хеш итераций. Для разумной безопасности рекомендуется использовать порядка 500 операций, которые занимают менее секунды на обычной рабочей станции.
Уязвимости
- При транспортировке контейнеров PKCS#12 защита данных реализована на основе пароля.
- Само собой разумеется, что хранение секретных ключей является очень безопасным, поскольку они хранятся в зашифрованном виде в формате, описанном RFC 5208.
Однако, это не верно и в отношении объектов сертификата. Причина этого в том, что обеспечение целостности PKCS#12-файлов не является обязательной, как показано здесь:
PFX ::= SEQUENCE { version INTEGER {v3(3)}(v3,...), authSafe ContentInfo, macData MacData OPTIONAL }
Так как этот контроль опционален, то он может быть отключён и тогда содержимое файла может быть изменено без обнаружения или предупреждения. Таким образом контроль доступа не требуется для добавления объектов сертификата. В этом случае сертификаты используются в SSL PKI как Trust Anchor и это даёт возможность злоумышленнику вставить Trust Anchor своего центра сертификации в эти файлы без необходимости какой-либо авторизации.
С того момента, как Trust Anchor злоумышленника вставлен в атакуемую систему она будет доверять и признавать любой сертификат, выпущенный центром сертификации атакующего.
Атака может быть произведена по схеме человек посередине, который перехватывает файлы во время транспортировки, вставляет вражеский Trust Anchor. В этом случае атака может так же работать против систем, не использующих PKCS#12-файлы, как хранилище ключей, но эта атака имеет недостаток, что фальшивый сертификат может быть обнаружен после выявления факта атаки.
Создание и преобразование сертификата
Расширение файла: «.p12» или «.pem». Эти файлы могут быть созданы с помощью OpenSSL.
Создание сертификатов PKCS#12
Основано на статье: Creating PKCS12 Certificates
Подготовка окружения
Создайте каталог (например, cert) и перейдите в него. Создайте в нём пустой файл certindex.txt Выполните команды:
mkdir private mkdir certs echo '100001' > serial touch certindex.txt
В этом каталоге создаём файл конфигурации openssl.conf следующего содержимого:
# # OpenSSL configuration file. #
# Establish working directory. dir = .
[ ca ] default_ca = CA_default
[ CA_default ] serial = $dir/serial database = $dir/certindex.txt new_certs_dir = $dir/certs certificate = $dir/cacert.pem private_key = $dir/private/cakey.pem default_days = 365 default_md = md5 preserve = no email_in_dn = no nameopt = default_ca certopt = default_ca policy = policy_match
[ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional
[ req ] default_bits = 1024 # Size of keys default_keyfile = key.pem # name of generated keys default_md = md5 # message digest algorithm string_mask = nombstr # permitted characters distinguished_name = req_distinguished_name req_extensions = v3_req
[ req_distinguished_name ] # Variable name Prompt string #------------------------- ---------------------------------- 0.organizationName = Organization Name (company) organizationalUnitName = Organizational Unit Name (department, division) emailAddress = Email Address emailAddress_max = 40 localityName = Locality Name (city, district) stateOrProvinceName = State or Province Name (full name) countryName = Country Name (2 letter code) countryName_min = 2 countryName_max = 2 commonName = Common Name (hostname, IP, or your name) commonName_max = 64
# Default values for the above, for consistency and less typing. # Variable name Value #------------------------ ------------------------------ 0.organizationName_default = Company localityName_default = Moscow stateOrProvinceName_default = Moscow countryName_default = RU emailAddress_default = email@domain.ru commonName_default = Common text
[ v3_ca ] basicConstraints = CA:TRUE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always
[ v3_req ] basicConstraints = CA:FALSE subjectKeyIdentifier = hash
Создание сертификата сертифицирующей организации
openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -days 365 -config ./openssl.conf
При запросе пароля указывайте пароль не менее 4 символов. На все остальные запросы можно нажать Enter.
Создание пользовательского сертификата
Сначала зададим имя для файлов сертификата пользователя. Так как их может быть много, задание через переменную среды окружения позволит повторять этот шаг очень быстро для каждого пользователя.
name='user'
Теперь для каждого пользователя создаём сертификат PKCS12. Выполняйте по одной команде:
openssl req -new -nodes -out $name-req.pem -keyout private/$name-key.pem -days 365 -config ./openssl.conf
openssl ca -out $name-cert.pem -days 365 -config ./openssl.conf -infiles $name-req.pem
openssl pkcs12 -export -in $name-cert.pem -inkey private/$name-key.pem -certfile cacert.pem -name "description" -out $name-cert.p12
При запросе пароля указывайте пароль, заданный при создании сертификата CA. На все остальные запросы можно нажать Enter.
Готовый файл: user-cert.p12
Этот файл можно импортировать в Firefox или Thunderbird, а потом использовать в OpenOffice.org.
Преобразование сертификата в формат PKCS#12
Предположим, что нам необходимо создать файл cert.p12. Допустим, что у нас имеются файлы с закрытым ключом prkey.pem и файл с сертификатом cert.pem. Выполнить это можно с помощью команды openssl pkcs12:
openssl pkcs12 -export -in cert.pem -inkey prkey.pem -name "My Certificate" -out cert.p12
здесь -name это ключ, которым задается идентификатор вашего сертификата. Таким образом в нашем примере строка «My Certificate» будет отображаться в пользовательской программе. При попытке обратиться к сертификату вас вначале попросят ввести пароль к текущему закрытому ключу, а потом пароль от PKCS#12-файла (*.p12). Причем пароль от PKCS#12-файла запросят два раза.
Создание списка недействительных сертификатов
По истечении определённого срока сертификат становится недействительным. Если это сертификат сотрудника, то, например, после его увольнения сертификат необходимо считать недействительным. Если секретный ключ сертификата стал достоянием общественности по каким-либо причинам, то его тоже необходимо внести в список недействительных сертификатов (CRL). Для управления CRL можно воспользоваться командой openssl ca.
Создание CRL:
openssl ca -gencrl -out crl.pem
Добавление ненужных сертификатов осуществляется с помощью команды:
openssl ca -revoke bad_cert.pem
После каждого применения revoke необходимо обновлять CRL командой
openssl ca -gencrl
Больше информации можно узнать в мануале, использовав в терминале Linux команду man pkcs12 или по ссылке pkcs12(1).
Библиотека JSSE
Данный раздел основан на LirJSSE — расширение безопасных сокетов с поддержкой алгоритмов ГОСТ для Java. Для получения большей информации о том, как PKCS#12 реализован в библиотеке JSSE рекомендуем обратиться к источнику.
Провайдер SunJSSE предоставляет полную реализацию java.security.KeyStore формата PKCS#12 для чтения и записи файлов pkcs12. Этот формат также поддерживается другими инструментами и приложениями для импорта и экспорта ключей и сертификатов, такими как Netscape/Mozilla, Microsoft Internet Explorer и OpenSSL. Например, эти реализации могут экспортировать сертификаты и ключи клиента в файл с расширением «.p12».
С провайдером LirJSSE, вы можете получить ключи PKCS#12 через KeyStore API с типом хранилища «pkcs12». Кроме того, вы можете просмотреть список установленных ключей и соответствующих сертификатов с помощью команды keytool с опцией -storetype установленной в pkcs12.
На всякий случай, нужно иметь в виду, что в Java 6 JDK одни и те же классы поддержки хранилища PKCS#12 содержатся не только внутри JSSE, но и отдельно в пакете sun.security.pkcs12.
Реализация хранилища PKCS#12 в LirJSSE дополнительно поддерживает алгоритмы ГОСТ. Далее описываются особенности этой реализации.
Особенности реализации PKCS#12 в LirJSSE
При загрузке хранилища проверяется его целостность по дайджесту, после чего расшифровываются все цепочки сертификатов. Секретный ключ расшифровывается только по запросу с указанием конкретного алиаса, но в открытом хранилище продолжает находиться в зашифрованном состоянии. Шифрование всех цепочек сертификатов и вычисление дайджеста хранилища производятся только при сохранении хранилища в файле.
Цепочки сертификатов связываются с секретными ключами внутри хранилища по локальным идентификаторам. Локальный идентификатор — это массив байтов в формате UTF-8, образованный при добавлении нового ключа из строки "Time ", за которой следует текстовое представление даты и времени добавления элемента. При добавлении нового ключа всегда задаются также соответствующая цепочка сертификатов и пароль.
Новый секретный ключ может быть представлен для добавления в хранилище в открытой форме, либо в уже зашифрованном виде. В последнем случае пароль ключа не указывается.
В хранилище не могут одновременно содержаться ключи ГОСТ и не ГОСТ. Соответствующий внутренний тип хранилища устанавливается либо при его загрузке, либо при добавлении первого ключа. Если хранилище пустое, то тип его в этом смысле не определён.
Алиас ключевого элемента, вообще говоря, не обязателен. Если в хранилище оказался элемент без алиаса, то алиас ему назначается принудительно в виде внутреннего порядкового номера. Дело в том, что LirJSSE, как и Sun JSSE, работает с элементами хранилищ только по алиасам.
При создании элементов хранилища различными программами может несколько отличаться внутренняя структура хранения зашифрованных элементов. Из-за этого, например, одна и та же цепочка сертификатов может упаковаться в файле хранилища средствами LirSSL и LirJSSE в структуры разного размера. Стандарт это допускает, и на функциональность хранилища это не влияет.
При работе с JSSE не нужно забывать, что пароли ключевых элементов должны совпадать с паролем хранилища. Стандарт PKCS#12, вообще говоря, допускает использование различных паролей в одном хранилище, но SunJSSE и LirJSSE не поддерживают данную возможность.
По договорённости с фирмой Топ Кросс, пароль всего хранилища перед применением преобразуется в программе LirJSSE в формат UTF-16 (последние два байта — нулевые). А отдельные элементы хранилища защищаются тем же паролем, но в формате UTF-8.
В LirJSSE — расширение безопасных сокетов с поддержкой алгоритмов ГОСТ для Java приводится сравнительное описание внутренней структуры файлов хранилища PKCS#12 в формате ASN.1 для вариантов RSA и ГОСТ.
Схема работы агентства по выдаче персональных сертификатов
- Пользователь заходит на сайт и просит сертификат.
- Устанавливается безопасное соединение.
- Клиент заполняет форму регистрации (включая пароль секретного ключа).
- На сервере создаётся запрос на сертификацию.
- На основе сертификата организации создаётся сертификат клиента.
- Сертификат перегоняется в формат PKCS#12 и записывается на диск.
- Пользователю на почтовый ящик отправляется ссылка на полученный сертификат.
- Клиент переходит по ссылке вводит своё имя и пароль (в безопасном режиме — https).
- При правильном вводе клиент перенаправляется к своему сертификату.
- Браузер получив сертификат проверяет его подпись и после запроса помещает в хранилище личных сертификатов.
Использование
- Такие сертификаты используются в качестве ключей на защищённых веб-страницах и в электронной подписи OpenOffice.org.
- PKCS#12-файлы используются во многих браузерах и почтовых агентах, таких как Netscape Navigator, MSIE, MS Outlook.
- PKCS#12 используется в MatrixSSL, начиная с версии 3.3.2.
См. также
Примечания
Ссылки
- OpenSSL PKCS #12 FAQ Архивная копия от 17 февраля 2020 на Wayback Machine
- PFX — How Not to Design a Crypto Protocol/Standard, Peter Gutmann
- Fixing Private Key Transport, Peter Gutmann, Blake Ramsdell, October 7, 1998
- Creating PKCS12 Certificates
- PKCS #12 File Types: Portable Protected Keys in .NET
- pkcs12(1)
- OpenSSL PKCS#12 FAQ v1.84 Архивная копия от 17 февраля 2020 на Wayback Machine
- LirJSSE — расширение безопасных сокетов с поддержкой алгоритмов ГОСТ для Java