cr
|
опубликован 27-12-2001 10:02 MSK
Описание механизма функционирования парольных кешей в Windows 95/98 (PWL-файлы). Часть 1. (c) 1998-2000, Владимир Калашников (AKA Hard Wisdom) 0. О теме разговора Сейчас мы с вами поговорим о парольных кэшах Windows v4.xx. Под парольным кэшем понимается механизм сохранения и повторного использования паролей в системе. От обычной базы логинов данный механизм отличается именно хранением дополнительных парольных ресурсов и возможностью их использования по специальному запросу без участия пользователя. Для чего появился данный механизм? Отчасти для облегчения работы пользователей ;-) Интересно, все для них... А во вторых... Можно расценивать это как дополнительный защитный механизм. Достоинством является затруднение "подглядывания" за клавиатурой, уменьшение количества ошибок при вводе паролей и возможность использользования паролей большей длинны (нет нужды их запоминать или записывать на бумажке). Недостатками - возможность получения существенного объема "секретной" информации злоумышленником при взломе парольного кэша, крайне несерьезная реализация данного механизма в имеющихся версиях операционной системы Windows. Появился данный механизм работы с парольными ресурсами относительно давно. Определенные предпосылки реализации были заложены еще в Windows v3.11. Ничего не могу сказать про эту систему, т.к. сам прыгнул из MS-DOS'a сразу в Windows v4.0. С нее и начнем. А пока позвольте рассказать о том как все выглядит снаружи. Способность кэшировать парольные ресурсы появляется в Windows при установке "сетевого окружения" или "множественных параметров рабочего стола" (блин, ну и названия). Политика функционирования подсистемы кэширования определяется редактором системных правил PolicyEditor (его можно взять из пакета Resources Kit от Micro$oft), по умолчанию кэширование включено (это означает, что его можно выключить). Обычно на такие мелочи никто внимания не обращает. Кэширование паролей - общесистемный сервис, это значит, что любое приложение может получить к нему доступ. Очевидно предполагалось, что компьютер физически надежно защищен (ибо персональный ;-), разумеется, в реальной жизни это не так. Как же предполагалось легальным способом использовать данный сервис? Приложение (например Explorer a.k.a. "проводник", гильдии Ивана Сусанина ;-) пытается подключиться к сетевому (и не только) ресурсу, функция WNetAddConnection возвращает код результата ERROR_INVALID_PASSWORD или ERROR_ACCESS_DENIED, в таком случае выводится стандартный диалог запроса пароля (для любителей, можете написать перехватчик данного диалога, в частности, это будет WNetConnectionDialog), затем производится повтор попытки подключения, в случае успеха пароль заносится в кэш паролей и в дальнейшем делается попытка его использования именно оттуда (при возникновении проблем происходит переключение на "ручное управление"). Как использовать данный сервис нестандартно? а вот как: IMPORTS WNetEnumCachedPasswords = MPR.WNetEnumCachedPasswords and than: Push 0 Push Offset AcceptCache Push 0FFh Push 0 Push 0 Call WNetEnumCachedPasswords Где процедура AcceptCache является точкой обратного вызова и принимает два параметра, первый из которых - адрес элемента парольного кэша, про структуру кэша мы поговорим дальше. В вашей программе можно писать так: Mov EAx,[ESp+4] ............... Ret 8h На самом деле ничего писать не надо, все уже и так реализовано в моей программе PWLHACK v4.02, которую можно взять по адресу указанному в конце этой статьи. Как вы уже успели понять, на залогиненной машине возможно элементарно получить весь список парольных ресурсов со всей сопутствующей критической (с точки зрения безопасности) информацией. Виват, Micro$oft! Кстати, во всей литературе, которую я читал про защиту информации, слова MS-DOS и Windows не упоминаются вообще (разве что во введении, причем единожды ;-). В принципе, описанный выше механизм работы с парольным кэшем суть существенный просчет (даже на фоне прочей дырявости) в системе безопасности Windows. Раз уж я заговорил о дырках... скажу еще пару слов (все это делает PWLHACK v4.02), ресурсы предоставляемые машиной в сеть для публичного использования хранятся в регистри (причем вместе с паролями). Вот как это происходит: Software\Microsoft\Windows\CurrentVersion\Network\LanMan. Начиная отсюда под ключами располагаются сетевые каталоги плюс вспомогательная информация (флаги, пароли и проч.) Хотите знать механизм шифрования паролей? Вот он: Seed=6Ah; ForEach Password (Ror Seed,1; Character Xor Seed) Все желающие могут чуть-ли не батником добавлять шаровые ресурсы в машину (при условии физического доступа к ней). Управлением локальными ресурсами машины, предоставляемыми в сеть, занимается VSERVER.vxd, а обменом информацией с удаленными серверами VREDIR.vxd Безусловно, в связке работают так же MSNET32.dll, MSNP32.dll и проч. Физически парольный кэш располагается в каталоге %WINDIR% и имеет расширение .PWL, причем список файлов, составляющих парольный кэш, находится в SYSTEM.ini в разделе [Passwords Lists]. Интересен такой момент, имя файла есть имя пользователя обрезанное до 8 букв (8.3 стандарт на имена файлов). Если имена 2-х пользователей совпадают в первых 8-ми буквах, и различны, то работать сможет только второй из них, первый потеряет все настройки, т.к. парольный файл второго затрет аналогичный файл существовавший до него. Никаких проверок не производится, уф! Физически всю работу производит модуль MSPWL32.dll Кстати, еще один факт слабой проработки кодирования защитных модулей, заменой 3-х байтов полностью отключается весь механизм шифрования файлов, составляющих парольный кэш, затем due to технические причины автоматически является легальным любой вводимый пароль, вот иллюстрация: -[MSPWL32.crk]-------------------------------------------------------- Windows 95-98 passwords. (C) by *HW* [W95 & OSR/2] All passwords are legal and *.PWL's are not encrypted. MSPWL32.DLL 00000511: 30 90 <ик> 00000512: 0C 90 00000513: 28 90 [W98 4.10.1691] All passwords are legal and *.PWL's are not encrypted. MSPWL32.DLL 00001241: 30 90 00001242: 0C 90 00001243: 28 90 -[MSPWL32.crk]-------------------------------------------------------- Заменяемые байты есть команда наложения гаммы на файл (XOR кого-то с кем-то), об этом мы поговорим подробнее чуть ниже. При обработке файлов используются алгоритмы RC4 (RFC-.... ну нет у меня интернета) и MD5 (RFC-1321). На настоящий момент уже появился алгоритм RC5 (можно ожидать его применения в дальнейшем). Алгоритм RC4 является алгоритмом потокового шифрования и считается вполне устойчивым, MD5 - алгоритм создания дайджестов (сверток) сообщений, достаточно быстр в реализации, разработчик R.Rivest. Про MD5 мы поговорим особо в дальнейшем. Итак, подошло время технической информации. 1. Обзор реализации парольных кэшей Windows v4.0 (a.k.a. 95) Для начала я приведу Си-подобную структуру расписывающую отдельные поля этого файла, затем будут комментарии. #define W95_PwlSign 0x4E464DB0 // Some guys call it "MFN" #define W95_PwlBase 0x23C
typedef struct { /* version depended W95 PWL partition */ byte UserName[20]; /* Padded owner name */ word ResOffsets[0xF]; /* Resources offsets. */ } W95_pwl_data; typedef struct { /* PWL file header itself */ dword Sign; /* .PWL file signature */ dword UnknownC; /* ?? Strange counter */ byte ResLink[0x100]; /* Resource link index */ byte ResKey[0x100]; /* Resource key entry */ union { W95_pwl_data W95_Data; /* W95 format PWL data */ OSR_pwl_data OSR_Data; /* OSR format PWL data */ } HdrV; } pwl_hdr; Итак, файл содержит в самом начале сигнатуру W95_PwlSign, заголовок имеет размер W95_PwlBase, собственно, с этого смещения располагаются (обычно) зашифрованные ресурсы. Поле UnknownC увеличивается с течением времени при модификации файла и является скорее всего версией парольного кэша (вернее не столько версией, сколько возрастом). Теперь ключевой момент, доступ к ресурсам. Он осуществляется по 16-ти точкам входа (соответствующая индексация осуществляется по телу ресурса), это позволяет значительно ускорить доступ к ресурсной информации и не расшифровывать лишний раз "критические" данные (впрочем, их все равно потом в памяти _не_ затирают). Лирическое отступление: я часто замечал вольную работу со стеком и регистрами библиотечных функций Windows (здесь и далее версия не ниже 4.0). Имеется ненулевая вероятность получения интересной информации после отработки многих системных вызовов. (Скажем, многие функции осуществляют поиск файла по системному маршруту: текущий каталог, затем %WINDIR%, затем PATH и т.п. Достаточно часто после выхода из такой функции в EDx содержится указатель на полный путь найденного файла, это лишь пример... Только пример для думающего человека...) Собственно, файл кэша может содержать максимально 255 ресурсов. Поля массива ResLink[] содержат номера ресурсов (в случае, если необходим итеративный, а не ассоциативный доступ), эти поля индексируют поля ResKey[], содержащие номера точек входа (другими словами - номера каналов ресурсов) в ресурсном файле. Почему именно такая двухуровневая система? Возможно по соображениям простоты вставки-удаления элементов (ну лень им было возиться со списками и проч., файлы, кстати, вычитываются по кусочкам, т.е. по 2-4-...-256 байта, как раз полями). Открытие парольного кэша осуществляется следующим образом: сворачивается пароль в 4-х байтовый хеш, затем по хешу строится таблица RC4 и осуществляется расшифровка полей UserName и ResOffsets, поле UserName должно содержать имя пользователя. Ресурсы в каждом канале зашифрованы независимо друг от друга, но одним и тем же ключевым значением. Вспомним о том, что RC4 потоковый алгоритм. Практически всегда зная имя пользователя (которое выровнено 0-ми на 20-ти байтовую границу) мы получаем начало гаммы, затем предполагая определенные значения смещений ресурсов (на основе полей ResKey и ResLink, а так же знания константы W95_PwlBase) мы можем получить еще несколько (до 15*2) байтов гаммы, итого max 50 байтов гаммы, это позволит нам расшифровать max по 50 байтов каждого ресурсного входа, абсолютно без всякого предположения о пароле пользователя. Данную задачу решала программа Glide в свое время. Этот нюанс в применении стойких криптоалгоритмов даже явился источником нескольких журнальных статей в околокомпьютерной журналистике. В настоящее время это уже история, так как только у нас еще используют чистую Windows v4.0 без обновлений. Второй путь: ключ для RC4 шифрования короток, 2^32, полный перебор может быть осуществлен за сутки (даже менее). А это значит, что парольные кэши Windows v4.0 гарантированно _не_ защищают хранящуюся в них информацию. Рассмотрим поближе формат канала ресурсов, именно в таком формате ресурсы получает точка обратного вызова для WNetEnumCachedPasswords (по одному ресурсу на вызов). Offset Size Meaning 0 Word Total resource size 2 Word Resource descriptor size (name of a link, network drive, game server e.t.c.) 4 Word Security information size (password for link, for network printer e.t.c. ) 6 Byte Resource number (absolute) 7 Byte Resource type descriptor (6-DialUp, 3-NetLink, e.t.c.) Стоит добавить, что ресурсы далеко не всегда текстовые строки. MAPI хранит в парольных кэшах свои бинарные данные, а Novell Network Provider хранит имя пользователя и логин на сервер как 2 строки закрытые 0 в "секретном" поле ресурса. Все желающие поисследовать файлы .PWL могут воспользоваться ключем /LIST:E программы PWLHACK v4.02 Еще один момент: это процедура свертки пароля в Windows v4.0 Очевидно, что такая свертка достаточно просто обратима (возможна генерация некоторого множества паролей для отдельно взятого хеша). ; EDx - hash, EBx - Pointer to password. W95_Hash_Pwd Proc Xor EDx,EDx W95_Hash_Next: MovZx EAx,Byte Ptr [EBx] Add EDx,EAx Rol EDx,7 Inc EBx Or Al,Al Jnz Short W95_Hash_Next Ret W95_Hash_Pwd EndP Наверное, мне больше нечего добавить в этом разделе, думаю, что пора переходить к следующему. Micro$oft иногда прислушивается к мнению "прогрессивной общественности", особенно в вышеописанном случае, иначе она не была бы Micro$oft. 2. Обзор реализации парольных кэшей Windows v4.0.1111 (a.k.a. 95 OSR2) Начнем как обычно, с Си-подобного заголовка .PWL файлов этой версии Windows, продолжим пояснениями. #define OSR_PwlSign 0x968582E3 // Somebody calls it "“‚…–" #define OSR_PwlBase 0x290 #define OSR_PwlHdrOfs 0x252 typedef struct { /* OSR PWL checking sign */ byte CryptoSign[0x10]; /* Crypto sign */ byte CheckoSign[0x10]; /* Checko sign */ word ResOffsets[0xF]; /* Resources offsets. */ } check_pack; typedef struct { /* version depended OSR PWL partition */ dword HdrOfs; /* Offset to CryptoHdr */ dword CryptoSeed[0x11]; /* Resource CryptoSeed */ word UnkAlign; /* ?? Just alignment */ check_pack Check; /* Checking crypt-sign */ } OSR_pwl_data; typedef struct { /* PWL file header itself */ dword Sign; /* .PWL file signature */ dword UnknownC; /* ?? Strange counter */ byte ResLink[0x100]; /* Resource link index */ byte ResKey[0x100]; /* Resource key entry */ union { W95_pwl_data W95_Data; /* W95 format PWL data */ OSR_pwl_data OSR_Data; /* OSR format PWL data */ } HdrV; } pwl_hdr; Общая структура файла осталась без изменений, те же ресурсные входы, механизм доступа по каналам (точкам входа) и проч. Но что-то ведь изменилось? Как минимум, изменилась сигнатура файла, теперь это OSR_PwlSign, соответственно изменилось и положение ресурсной информации, она теперь обычно располагается по смещению OSR_PwlBase Появилось дополнительное поле HdrOfs имеющее как правило значение OSR_PwlHdrOfs, по данному смещению располагаются описатели ресурсных точек входа (смещения внутри файла, соответственно размер ресурсного канала есть ResOffsets[i+1]-ResOffsets[i]), ну, если более точно, то структура check_pack. Поскольку работа с ресурсами была описана выше, то перейдем к новому моменту: открытию парольного кеша. И вот теперь начинаются проблемы. Первоначально пароль вместе с константой 0xFFFFFFFF, а так же CryptoSeed[0x10], именем пользователя и паролем сворачивается в MD5 хеш, длинной 4 DWord'a (за 2 прохода, вначале имя, затем пароль). После этого расшифровывается участок файла check_pack (алгоритмом RC4), затем выполняется еще одна MD5 свертка, в ней участвуют имя пользователя и поле CryptoSign[] в результате должна получиться сигнатура CheckoSign[], тогда и только тогда пароль расценивается допустимым. Как видим, исправлены все недостатки предыдущего формата ресурсного файла. В частности, реализация переборщика показала, что скорость снизилась в 2 раза, по сравнению с вариантом из Windows v4.0 (38 тыс. pps против 55 тыс. pps) Исправлены также недостатки малой длинны свертки пароля и тривиальная зависимость свертки от пароля. Хочется отметить такой факт, что поля ввода в диалогах позволяют ввести пароль максимально до 14 символов и преобразуют его к верхнему регистру (справедливо для версий Windows v4.0-4.0.1111). Это существенно сокращает пространство для перебора. А как с одиноковой гаммой для каждого ресурсного канала? Теперь, при создании ключа для шифрования, используют поля CryptoSeed[i], причем пропускание этой информации сквозь MD5 не позволяет говорить о прямой реконструкции гаммы даже при знании некоторых ресурсов. 3. Дополнения и изменения в операционной системе Windows v4.1 (a.k.a. 98) Их очень немного, прежде всего, сняли ограничения с полей ввода в диалоговых окнах (теперь можно ввести свыше сотни символов в имя пользователя и в пароль). Так же, при логине имя пользователя выбирается из списка, что позволяет достаточно просто использовать длинные имена пользователей (что очень замедляет перебор). Жаль, но пароль из списка выбирать нельзя ;-) Вот и все, форматы файлов изменений не претерпели. Была дополнительно переписана MSPWL32.dll, конечно же она стала в 2 раза больше объемом (такое ощущение, что мировые производители винчестеров - одно из подразделений фирмы Micro$oft). Больше назвать нечего. 4. Детали реализации алгоритмов Исходные тексты криптоалгоритмов RC4 и MD5 доступны на FTP-сервере ftp://ftp.funet.fi/pub/crypt/ |
cr
|
опубликован 27-12-2001 10:10 MSK
Формат PWL-файла Содержимое PWL-файла производит весьма мутное впечатление. Строгая документация от MicroSoft по этому вопросу отсутствует due to security (саркастический смешок) reason, а сам я разбирался лишь в меру необходимости. Поэтому правильнее озаглавить - примерный формат PWL-файла, в предположении, что в нем не более 16-и ресурсов (похоже, что PWL-файл может содержать только кратное 16-и число ресурсов, используемых и неиспользуемых, но мне ни разу не попадался экземпляр более чем с 16-ю ресурсами). 0000: 4 байта - магическое число или сигнатура. Просто безполезное число. В разных форматах PWL-файлов оно разное. Чем и помогает их различать : B0 46 4D 4E - Win3.11/Win95 E3 82 85 96 - OSR2/Win98 0004: Дв. слово - очень странный счетчик. Что-то явно считает, но что ? 0008: Таблица из 256-и байт. Гордо называется Resource Link Index. Странная таблица. Ясно, что нулевой байт означает неиспользованный элемент. Но какая польза с ненулевого байта - не совсем ясно. Если в этой таблице встречается ненулевой байт N, то это означает, что в следующей таблице используется (не равен FF) элемент по смещению 108h+N. Но всю полезную информацию можно сразу извлечь из второй таблицы, не обращаясь к первой. 0108: Безхозный нулевой байт. Никому не мешает. 0109: Таблица Resource Key Entry из 255-и байт. Теперь неиспользуемый элемент обозначается уже байтом FF. Вероятно между созданием первой и второй таблиц программистом был пропущен стаканчик. Если в этой таблице находится M байтов N, не равных FF, то это означает, что в ресурсе номер N содержится M парольных записей. Обшее число не равных FF байт в таблице равно общему числу парольных записей. Отсюда ясно, что в PWL-файле не может быть более 255-и парольных записей и более 255-и ресурсов, их содержащих. 0208: 20 байт - имя пользователя в верхнем регистре, дополненное справа нулевыми байтами (русские буквы в Альтернативной кодировке). Данное поле служит для странного алгоритма определения подлинности пароля. Имя пользователя можно посмотреть в файле system.ini, в свойстве Password Lists и, если оно не длиннее восьми символов, то оно будет совпадать с именем PWL-файла. 021C: 17 слов - таблица указателей на начала ресурсов. 21C:Смещение в файле начала ресурса 0, относительно начала файла 21E:Смещение в файле начала ресурса 1, относительно начала файла 220:Смещение в файле начала ресурса 2, относительно начала файла ... 23A:Смещение в файле начала ресурса F, относительно начала файла 23C:Смещение первого байта за концом файла (равно длине файла). Обе записи 208h-21Bh и 21Ch-23Dh образуют единое поле, которое зашифровано гаммой, накладываемой начиная со смещения 208h. 023E: Ресурс 0 Ресурс 1 Ресурс 2 ... Ресурс F В одном ресурсе может быть несколько парольных записей, следующих одна за другой. Первое слово каждой записи представляет собой длину записи, включая и это слово. Признаком конца цепочки записей является нулевое слово. Таким образом пустой ресурс - это просто нулевое слово. Тогда ясно, что если PWL-файл имеет длину 606 байт, то все ресурсы в нем пустые, т.к. 23Eh + 16*2 = 25Eh = 606. Каждый ресурс зашифрован гаммой, которая накладывается, начиная с его начала.
PWL-файл шифруется простым гаммированием, гамма генерируется алгоритмом RC4. При первой регистрации пользователя запрашивается пароль. Он приводится к верхнему регистру и сворачивается в ключ (двойное слово). Из этого ключа порождается гамма (псевдослучайная последовательность нулей и единиц). Эта гамма сложением по модулю два накладывается на каждый из ресурсов с его начала и зашифровывает их. Аналогично ресурсам зашифровывается поле 208h-23Dh, где хранится имя пользователя, и таблица указателей на начала ресурсов. При последующих регистрациях данным пользователем запрашивается пароль. Он приводится к верхнему регистру, опять сворачивается в ключ, из которого опять порождается гамма. Если этой гаммой имя пользователя в поле 208h-21Bh расшифровывается правильно, то пароль считается введенным правильно. После чего расшифровывается таблица указателей на начала ресурсов и сами ресурсы PWL-файла. Расшифровка производится вторичным наложением гаммы сложением по модулю два (используется обратимость сложения по модулю два, то есть тот факт, что (X XOR Y) XOR Y = X ). Если имя пользователя не расшифровывается правильно, то пароль считается неправильным. Таким образом, проверка правильности введенного пароля производится по совпадению первых 20-и байт порожденной из него гаммы с первыми 20-ю байтами гаммы от правильного пароля. Этот алгоритм определения подлинности пароля является весьма оригинальным, т.к. при этом нигде не сохраняется ни зашифрованный пароль, ни хеш-функция (необратимое преобразование) пароля. Но, в тоже время, на удивление, нелепо реализованным. Ведь поскольку имя пользователя известно ЗАРАНЕЕ, то первые 20 байт гаммы тривиально вычисляются. Но, т.к. ТА-ЖЕ гамма накладывается на каждый ресурс (отсутствие смены гаммы при шифровании разных полей - это основная ошибка применения алгоритма RC4 в данном случае), то можно расшифровать и первые 20 байт каждого ресурса ! PWL-файл имеет избыточную информацию - есть указатели на начала ресурсов, но есть и длины записей в ресурсах и из одного можно вычислять другое. Если в ресурсах не более одной записи, то длина ресурса есть первое слово ресурса плюс два (длина первой записи ресурса плюс длина нулевого слова). Определяя по началу и длине данного ресурса начало следующего, рассчитывается вся таблица указателей на начала ресурсов в поле 21Ch-23Dh. В результате еще 2*17 = 34 байта добавляются к рассчитанной гамме. Если в ресурсах более одной записи, то начало следующего ресурса все равно можно найти с некоторой долей вероятности (после наложения гаммы второй байт ресурса будет равен второму байту гаммы, т.к. длина записей в ресурсе редко превышает 255, а 0 XOR X = X ). Этот алгоритм реализован в известной программе Glide (ftp://195.16.108.4/pub/serial/hackers/leoworld/cracks/glide.zip), которая рассчитывает 54 первых байта гаммы и расшифровывает по 54 первых байта каждого ресурса. Причем немедленно и без какого либо перебора вариантов, что сводит прочность системы шифрования Win95 к НУЛЮ (под прочностью системы шифрования понимается количество вариантов, которые необходимо перебрать для ее гарантированного вскрытия). Между тем, достаточно было накладывать гамму на ресурсы, не используя первых засвеченных ее байт, чтобы такой огромной прорехи не было. Алгоритм генерации ключа по паролю (c) Microsoft Имеем Key - двойное слово и пароль до 20-и символов. 1) Обнулить Key. 2) Привести пароль к верхнему регистру (русские буквы приводятся к верхнему регистру в Альтернативной кодировке). 3) Для каждого символа пароля, начиная с первого : а) прибавить код символа к Key б) повернуть Key влево 7 раз. 4) На прощание еще раз вращать Key влево 7 раз. (программистам на Си этот шаг можно не делать, считая, что нулевой байт, завершающий строку с паролем, тоже является его символом, и повторить цикл 3 на один раз больше) Ключ используется для инициализации генератора псевдослучайных чисел (алгоритма RC4). Для каждого ключа RC4 порождает уникальную битовую последовательность (гамму). Алгоритм сопоставления ключа паролю слаб тем, что при выбранной длине ключа в двойное слово, множество различных ключей (2^32) оказывается неизмеримо меньше множества различных паролей. Это означает, что существуют пароли, которые Win95 не отличает друг от друга. Например, пароли <ARJEW> и <QRJEV> свернутся в один и тот же ключ A8B6:C694, породят одну и туже гамму и поэтому для Win95 полностью эквивалентны! В пароле могут использоваться 100 различных символов (26 латинских букв + 10 цифр + 32 спецсимвола + 32 русские буквы). Отсюда 1+100+100^2+100^3+100^4+...+100^14 ~ 100^14 = 10^28 - множество различных паролей от пустого до 14-символьных. 2^32 = 4*((2^10)^3) ~ 4*((10^3)^3) = 4*10^9 - множество различных ключей. (здесь везде ~ - примерно равно). Т.е. множество возможных ключей на много порядков меньше множества возможных паролей. Это делает совершенно бессмысленными допускаемые в Win95 длинные пароли. Поскольку 2^32 < 100^5 , то эффективная длина пароля соответствует только ПЯТИ символам ! Это, правда, совершенно не означает, что для каждого пароля найдется пятисимвольный эквивалент, т.к. множество паролей при таком алгоритме очень неравномерно отображается на множество ключей. Но мне удалось построить алгоритм, который для любого значения ключа немедленно, то есть без перебора, вычисляет подходящий девятисимвольный пароль из следующего множества символов <@ABCDEFGJKNOPQRSTUVWX>. Так что доказано, что ЛЮБОМУ паролю в Win95 найдется эквивалент не длиннее ДЕВЯТИ символов! Поэтому задавать более длинные пароли совершенно бессмысленно! Пустому паролю соответствует нулевое значение ключа. Возникает интересная задача: существует ли пароль, который бы Win95 не отличала от пустого пароля ? Удивительно, но существует !!! Мне удалось найти 16 девятисимвольных таких паролей, состоящих из одних латинских букв. Из них наиболее симпатичный <FFFFKKKKL>. Также нашел 8 восьмисимвольных с одним специальным символом <{< - например <FFFO{KKL> или <GGGO{CCD> и поэтому менее красивых. Более короткие такие пароли невозможны. |