Как стать автором
Обновить

Комментарии 15

У того самого asn1 editor, которым вы пользовались для просмотра сертификата есть обычный шарповый метод
Asn1Parser.GetNodeByOid(string oid)


А ещё можно обойтись коробочными решениями, там есть всё, чтобы прочитать сертификат\подпись целиком.
Согласен, альтернативных решений может быть много. BouncyCastle выбран по понятной причине — чаще попадался на StackOverflow во время погружения в задачу, при этом простые примеры нужного нам обхода дерева после нескольких попыток так и не обнаружились.

Одна из идей третьей части (разработка парсера) — показать, что базовыми средствами .NET не очень удобно (читай, просто и логично) «прогуливаться» по дереву в поисках нужного OID'а.
Да уж сложно, но интересно.
А что сложного тут вообще было?
И цикл в парсере выглядит как-то не очень.
Если честно, «сложного тут вообще» было немного: "… вместо запланированных нескольких часов пришлось разбираться весь день. И еще два дня на подготовку исследования для Хабра."

Статья писалась с простой целью — сэкономить время другим читателям Хабра на тот случай, если они столкнутся с подобной задачей (и я надеюсь, поисковики начнут выдавать этот пост для тех, кто ищет «парсинг сертификатов x.509 с#», рядом с публикацией Разбираем x.509 сертификат как хорошее дополнение). Так что, позвольте считать время, потраченное на поиск решения, показателем сложности.

Это конечно, когда уже во всем разобрался, все кажется логичным и понятным. Но когда только начинаешь погружаться в криптографию, то понимаешь, что это ЖОПА. Ведь как думаешь в начале? Да что там, ведь столько компаний вбухивают бабла в нее, такой хайп стоит, "нескольких часов хватит", чтобы разобраться.


На деле же криптография — это какая-то секта избранных. Во-первых, очень сложно понять, с чего начать, где тот якорь, с которого начать раскрутку. Пресловутые несколько часов могут уйти только на его поиски. Во-вторых, вольные трактовки понятий. Подите с первого раза разберитесь, почему описание сертификата из RFC 5280 (структура Certificate) не соответствует тому, что лежит в файлах. Ответ — потому что там лежит структура контейнера, внутри которого и находится структура Certificate, и весь этот контейнер тоже почему-то называется сертификатом. Обычно это структура PKCS#7 и описана она в RFC 2315 (и то, еще нужно догадаться, что в файле именно она, RFC же только формат описывает. Помочь разобраться в этом могут парсеры ASN.1, о них ниже), а ведь есть еще PKCS#12 и, как вы догадываетесь, пропущенные номера также не пустуют. Разобраться во всех этих хитросплетениях без подготовки крайне тяжело. Номера RFC-шек между собой если и связаны, то явно эта связь для мозга, функционирующего отлично от человеческого.


Пикантности ситуации добавляет тот факт, что, например в джаве, стандартным криптографическим API от Sun-овского криптопровайдера файл с сертификатом не прочитать, т.к. API требует именно структуру Certificate на входе, а вот BouncyCastle тут дает поблажку и может сам выпарсить ее из контейнера. Что на мой взгляд плохо, т.к. заставляет полагаться на неочевидное и негарантированное поведение конкретного криптопровайдера. И вот представьте, хотите вы структурировать для себя информацию, делаете демо пример, и с одним провайдером он работает, а с другим нет! И вот сиди думай, где тут ошибки — у тебя или в одной из библиотек, а если в библиотеке, то в какой именно и что гуглить.


Потом идут поиски подходящего инструмента. Что толку, что все ссылаются на BouncyCastle? Заглянув туда в первый раз немного офигиваешь, что там за, ээ, оверинжиринг (я, правда, только его Java часть смотрел, но сомневаюсь, что в других местах лучше). Наивно думаешь, что уж в такой-то теме наверняка есть что-то более нормальное и логичное, с документацией.


Еще пару часов рыскаешь по гуглу, проникаешься разрухой. Хорошо, если к этому моменту удастся уже выйти на RFC (еще поди пойми, которое из них сейчас актуально!) с описанием всей этой криптографической мишуры. На этом этапе уже понимаешь, что BouncyCastle, в общем то, неплох — разбор ASN.1 структур там сделан неплохо. Собственно, пожалуй, только этим и можно нормально пользоваться, даже без документации, ее вышеприведенные RFC заменяет.


Автор в итоге и пришел к такому решению — используем хорошую часть библиотеки, забиваем на непонятную. Фактически при разборе сертификата нужно знать только его структуру, а она в RFC описана. Дальше только с помощью классов библиотеки парсим структуру и вытаскиваем нужное.


Ну и еще хотелось бы предостеречь читателей от статьи ASN.1 простыми словами (кодирование типа REAL). На мой взгляд, там не только простые слова, а героическое возведение и штурм укреплений, когда можно было пройти через ворота. Лучше ее не читать, только каши в голове добавит.


Да, и еще не могу не упомянуть замечательный сайт https://lapo.it/asn1js/ (у него есть и автономный режим работы — скачиваете html-ку) для декодирования ASN.1. Можно как вставлять как base64 так и hex, пробелы выкусываются автоматически

Только вот примерно все, описанное в топике, к криптографии не имеет ни малейшего отношения. Просто есть некий файл в ASN1/DER, который надо разобрать, понять, что внутри дерево, пройтись по нему и найти там нужное. Вместо ASN1 мог быть RIFF, TIFF, EBML, BSON, Protobuf, Apache Avro и т.д. — в общем, любой бинарный контейнер. Радикально ничего от этого не меняется.

Вместо ASN1 мог быть RIFF, TIFF, EBML, BSON, Protobuf, Apache Avro и т.д. — в общем, любой бинарный контейнер. Радикально ничего от этого не меняется.

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


Впрочем, соглашусь, что к академической криптографии описанное в посте действительно никак не относится. В академической криптографии вообще никаких контейнеров нет. Однако мы все же говорим о практическом применении. И форматы файлов — это тоже часть практической криптографии. Можете назвать еще хоть одну массовую, не нишевую, область, где ASN.1 используется? Сомневаюсь. Так что с практической точки зрения работа с ASN.1 почти равно криптографии. Или даже так: работа с ASN.1 почти всегда подразумевает касание криптографии.


Вместо ASN1 мог быть RIFF, TIFF, EBML, BSON, Protobuf, Apache Avro и т.д. — в общем, любой бинарный контейнер.

Это не совсем так. Скажем, если вы захотите сгенерировать подпись с помощью какой-то железки, которой на вход подают массив байт и ид. ключа в этой железке, а на выходе зашифрованный приватной частью этого ключа массив этих байт, то что вы будите делать? Если вы наивно полагаете, что достаточно будет запихать в нее те данные, что вы хотите подписать и получившийся массив записать в "любой бинарный контейнер", то вы заблуждаетесь. Потому, что по RFC для вычисления подписи шифруется не ваш массив, и даже не хеш от него, а хеш от ASN.1 контейнера специального вида, куда засунут хеш от вашего массива + описание алгоритма взятия хеша, параметры этого алгоритма и еще может быть чего. И шифруется уже этот контейнер, преобразованный в массив байт вполне конкретным способом.

Можете назвать еще хоть одну массовую, не нишевую, область, где ASN.1 используется?

Я могу назвать с десяток (вроде LDAP, SNMP, H.323, UMTS, LTE, WiMAX, 3GPP и вообще очень много всего в том, что касается телекомов и вокруг них), но вы удобно скажете, что это все "нишевые области". Впрочем, чем тогда "криптография" не нишевая?


Или даже так: работа с ASN.1 почти всегда подразумевает касание криптографии.

Если мы откроем какой-нибудь более-менее современный словарь, то прочитаем там что-то вроде: "Криптография — дисциплина, включающая принципы, средства и методы преобразования информации в целях сокрытия ее содержания, предотвращения видоизменения или несанкционированного использования."


И вот в посте ровно пример того, где работа с ASN.1 ну совсем никак не связана с использованием криптографии. Ничего не шифруется или подписывается с целью сокрытия содержания или защиты от изменений. Сертификат используется просто как источник данных. Если бы эти данные можно было получить, обратившись в какую-нибудь БД или веб-сервис — скорее всего так бы и сделали, а не разбирали сертификаты.

Телеком — это именно что нишевая область. Криптография не нишевая, потому что это чисто утилитарная область, само по себе она никому не сдалась, нужна только вместе с чем-то. И областей, требующих для себя криптографии, вполне много.


И вот в посте ровно пример того, где работа с ASN.1 ну совсем никак не связана с использованием криптографии

Ну да, ничего не шифруется и не проверяется. Согласен. Однако работать с ASN.1 приходится под соусом криптографии. Даже парсер ASN.1 является частью криптографической библиотеки, а не отдельной библиотекой. Потому что там он не абстрактный парсер контейнеров с информацией, а все-таки наделяет эти контейнеры каким-то смыслом. Вот здесь у нас ContentInfo, здесь SignedData, а здесь EnvelopedData. Это уже часть криптографической библиотеки. Можно эти структуры считать "средствами… преобразования информации" из приведенного вами определения?

LDAP забыли ;)

Когда занимался такими же задачами, то вместо ASN1 Editor использовал asn1js. Который отлично работает со строками. В ASN1 есть несколько типов строк, и ASN1 Editor кириллицу отображает плохо. А доработать код на C++ для поддержки Unicode не так-то просто.


И сделал пару доработок для asn1js, чтобы отображать СНИЛС, ИНН,… и иметь удобный способ сравнивать сертификаты/подписи.


К комитам есть скриншоты, посмотрите, может пригодится:



image

print description — классная фича, жалко, что похоже автор pull request-ы почему-то не принимает, но отослать все равно надо бы

Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории