Дополню. Пока меня не было видно на форуме я как раз задался вопросом извлечения сертификата из контейнера, кодировки ASN.1, безопасности хранения папок на диске NTFS, а также тестом совместимости считывателя съемных дисков с разными технологиями отображения папок (о тесте в другой раз, пока про ASN).
Сделал считывание дерева ASN "по слоям" - то есть для каждого тега сначала разделил содержимое между потомками. Если у тега есть установленный бит конструктивного кодирования 0x20 или тип OCTET STRING, то деление производится, иначе нет. Это правда дает много ошибок в случае, когда OCTET STRING на самом деле неделимый.
По такому принципу я пропускаю 2 слоя SEQUENCE (да как выше написали $headerKey.ChildNodes[0].ChildNodes[0]) далее ищу тег-потомок с длиной более 100 байт. 100 байт выбрано условно - из попадавшихся мне сертификатов самый маленький (и неквалифицированный!) был примерно 600 байт. С другой стороны, другие теги в header.key имеют длину явно меньше 100 байт (кроме расширений контейнера).
В данном случае, для сертификатов гост-2012 256 с dwKeySpec=KEYEXCHANGE тип тега мне везде попадался 0x85 (отмечу что бита конструктивного кодирования нет, сертификат включен как неделимый элемент). В только что сгенерированном контейнере - элемент отсутствует (то есть необязательный).
Тут нужно добавить, что формат header.key официально не опубликован, тем не менее по правилам номера из класса CONTEXT (0x85 = CONTEXT 5) присваиваются в описании типа последовательно и с учетом, что есть расширения сертификата CONTEXT 12, это наводит на мысль о существовании необязательных элементов со всем пропущенными номерами. По крайней мере, известно, что один контейнер теоретически может содержать 2 закрытых ключа (что очевидно как 2 пары primary + masks) и 2 сертификата (куда еще как ни в header.key). При таком количестве пропущенных элементов и необязательности сертификата - я бы не стал полагаться на выбор именно ChildNodes[3]. Более перспективно проверять код тега на соответствие 0x85 (но надо еще добавить номер для dwKeySpec=SIGNATURE) или на размер данных плюс неделимость элемента.
Еще хочу отметить, что при удалении расширений утилитой csptest - размер header.key не меняется, так что чтобы декодер не ругался на данные в конце файла не плохо после чтения установить размер данных по корневому элементу SEQUENCE.
P.S. Известно, что файлики составляющий контейнер без сертификата очень маленькие и (сюрпрайз! сюрпрайз!) файлы менее 1 Кб на самом деле хранятся NTFS без выделения кластеров на диске - прямо в записи о файле в файлах файловой системы $MFT и $MFTMirr. Получается, что контейнер как бы один, но хранится фактически в 2 местах на диске, что делает контроль непрозрачным. С другой стороны, так файлики не растянутся по всему диску плановой дефрагментацией и меньше риск их повредить при перезаписи. Файл header.key немного выбивается из шаблона - с сертификатом он более 1Кб и хранится в отдельном кластере, но там и так открытая информация.
Также известно, что во избежание сбоев $MFT и $MFTMirr изменяются не одновременно, а с разницей по времени. По разным косвенным признакам предполагается, что разница может быть сравнимой с интервалом обновления времени доступа к файлам - до часа. В связи с чем возникает вопрос: насколько эффективно затирание таких файлов (то есть перезапись содержимого файла случайными данными перед удалением)? Не может ли вторая копия (при синхронизации через значительный промежуток после удаления из первой копии) сразу выполнить освобождение места без затирания данных - оставить данные доступными пока место не заполнится?
В свете такой перспективы мне уже хочется перетащить все контейнеры на маленькие VHD, и затирать целиком весь VHD вместе с файловой системой. Жаль что букв дисков так мало. Либо добавить какой-то заполнитель места чтобы файлы стали больше 1 Кб плюс хранить на маленьком разделе с отключенной дефрагментацией.
Отредактировано пользователем 13 августа 2021 г. 8:34:03(UTC)
| Причина: Не указана