gifts2017

"Скажи пароль" или как работать со свойством СохраняемоеЗначениеПароля объекта типа ПользовательИнформационнойБазы

Опубликовал Константин Хрипков (mbreaker) в раздел Администрирование - Защита, права, пароли

Ряд статей уже затрагивали тему проверки текущего пароля пользователя и работу со свойством "СохраняемоеЗначениеПароля", но конкретики по данному вопросу мало. Данная короткая статья призвана исправить этот пробел.

Америку открывать никому не собираюсь, но как это ни странно, после получаса блуждания по просторам интернета я так и не нашёл конкретного описания, как можно сравнить введённый пароль с паролем текущего пользователя без его модификации (как это, например, реализовано в публикации 102655).

На деле всё оказалось довольно просто. В справке к свойству СохраняемоеЗначениеПароля объекта типа ПользовательИнформационнойБазы написано:

Содержит хранимые значения пароля (хеш-функции) и хранимые значения пароля в верхнем регистре (хеш-функции) разделенные запятой.

Только не указано, какие конкретно для этого используются хэш-функции. Для значения пароля "Привет" свойство содержит строку "KAWujn4S8YITX5L7kIQ7sQgNO+g=,c9a04UjoS/W0iLeU7GUa9/Ltd1E=".

Немного покопавшись в "сети", можно найти такую формулировку "sha-1, обёрнутый в base64". Складывая всё вместе, выводим следующий алгоритм:

Функция ПолучитьХешПароля(Пароль) Экспорт
	
	Хеш = Новый ХешированиеДанных(ХешФункция.SHA1);
	Хеш.Добавить(Пароль);
	Возврат Base64Строка(Хеш.ХешСумма);
	
КонецФункции

Проверяем на нашем пароле "Привет" и убеждаемся, что получившееся значение действительно совпадает с левой частью из сохраненного хеша.

Дальше с помощью функции получаем текущее значение свойства СохраняемоеЗначениеПароля, не забывая установить привилегированный режим (т.к. "доступно только пользователю с административными правами"), декомпозируем его на регистрозависимую (слева от запятой) и регистронезависимую (справа) части и сравниваем полученные значения.

Функция ПроверитьТекущийПарольПользователя(Пароль, РегистроНезависимый=Истина) Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	ХешТекущегоПароля = ПользователиИнформационнойБазы.ТекущийПользователь().СохраняемоеЗначениеПароля;
	УстановитьПривилегированныйРежим(Ложь);

	Если ХешТекущегоПароля = Пароль Тогда Возврат Истина КонецЕсли; // Пароль совпадает с СохраняемоеЗначениеПароля только в случае пустого значения
	
	ПозицияРазделителя = Найти(ХешТекущегоПароля, ",");
	Результат = Ложь;
	Если РегистроНезависимый Тогда
		Результат = ПолучитьХешПароля(ВРег(Пароль)) = Прав(ХешТекущегоПароля, СтрДлина(ХешТекущегоПароля) - ПозицияРазделителя);
	Иначе
		Результат = ПолучитьХешПароля(Пароль) = Лев(ХешТекущегоПароля, ПозицияРазделителя - 1);
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Вуаля! Ну, и на последок приведу еще функцию, формирующую значение свойства СохраняемоеЗначениеПароля из введенного пароля.

Функция ПолучитьСохраняемоеЗначение(Пароль) Экспорт
	
	Возврат ?(ЗначениеЗаполнено(Пароль),ПолучитьХешПароля(Пароль) + "," + ПолучитьХешПароля(ВРег(Пароль),"");
	
КонецФункции

См. также

Подписаться Добавить вознаграждение

Комментарии

1. OlgaMarvel (Olga_Analyst programmer) 28.01.15 15:42
Благодарю за статью, пригодилась.
2. bonv (bonv) 28.01.15 19:32
Как-то у вас получилось одевание штанов через голову. Не проще ли программно получать сохраняемое значение пароля и сравнивать его с хранимым в базе?

Не учитывается незаполненный пароль, для него сохраняемое значение пароля равно "".

Для себя когда-то сделал обработку (см. вложение).


Также в БП что-то похожее есть в модуле
ЭлектроннаяПодписьВМоделиСервисаСлужебный
Прикрепленные файлы:
ПроверкаПарольныхХешей.epf
3. rtnm rtnm (rtnm) 28.01.15 23:05
Меня смущает что 1С не использует при хэшировании "соль"(разную для каждого пользователя или хотя бы единую на всю базу). В этом случае восстановить(подобрать) пароли пользователей становится гораздо проще.
4. Константин Хрипков (mbreaker) 29.01.15 09:14
(2) bonv, за конструктивную критику о проверке на пустое значение благодарствую, в код добавил коррективы.
А вот про "одевание штанов через голову" давайте разберём, у кого же оно получилось "через голову".

Во-первых, откуда брать значение текущего пароля (из БД или из сеанса) - это исключительно зависит от подхода разработчика. Например, в НФ при смене пароля (меню Сервис - Параметры пользователя) разработчики платформы проверяют введённый пароль сеанса, т.е. из ПользователиИнформационнойБазы.ТекущийПользователь() (проверено эмпирически), разработчики БСП в приведённом Вами примере проверяют значение из БД, т.к. в функцию пользователь передается параметром.

Во-вторых, я совершенно не понял фразы "не проще ли программно получать сохраняемое значение пароля". А я его аппаратно что-ли получаю?

В-третьих, небольшой совет на будущее: прежде чем добавлять в свои сообщения едкий сарказм стоит получше вникнуть в комментируемый текст, дабы потом не было стыдно за сказанное. В статье приведён пример функции, которая в зависимости от передаваемого 2-го параметра сравнивает пароль в зависимой от регистра форме и в независимой. В какой форме проверять - остается на выбор использующего. В Вашей же обработке (как впрочем и в функции БСП) сравнение идёт только в регистрозависимом режиме, т.к. проверяются одновременно оба хранимых хэша.

Ну, и в-четвёртых, почему я не стал оборачивать этот код в обработку, а написал в статье? Потому что если внимательно почитать справку, а потом ещё внимательно почитать мою статью, для получения значения СохраняемоеЗначениеПароля необходимы административные права, а соответственно большинство пользователей использовать эту функцию через обработку не смогут, а установка привилегированного режима во внешней обработке бессмысленна. Соответственно делать это нужно во внутренних механизмах конфигурации, идеально для этого подходят общие формы. Поэтому публикация оформлена в виде статьи, а не обработки (как в Вашем случае).
5. Константин Хрипков (mbreaker) 29.01.15 09:16
(3) rtnm, меня много чего смущает в продуктах 1С... но преимущества пока перевешивают... ))
6. bonv (bonv) 29.01.15 09:57
(4) mbreaker,
1. В моем комментарии не было замечания по этому пункту
2.
я совершенно не понял фразы
действительно не поняли
3. Да, действительно, погорячился. Я был не прав, т.к. в моем случае всегда установлена проверка сложности паролей и соответственно используется регистрозависимая проверка. И для моих целей этого достаточно.
4. О какой публикации речь? Я приложил обработку (ее я сделал задолго до Вашей публикации с целью отладки своей функции), чтобы проиллюстрировать свой комментарий.
7. Константин Хрипков (mbreaker) 29.01.15 19:06
(6) bonv,
1. В моем комментарии не было замечания по этому пункту
было
сравнивать его с хранимым в базе
хоть, похоже, и не умышленно...

действительно не поняли
т.е. пояснений не будет?

в моем случае всегда установлена проверка сложности паролей и соответственно используется регистрозависимая проверка
к слову сказать, по умолчанию при штатной аутентификации 1С на входе проверка пароля производится без учета регистра (для этого-то в СохраняемоеЗначениеПароля и присутствует хэш пароля в верхнем регистре), но при установке в настройках ИБ (меню Администрирование - Параметры информационной базы...) галочки Проверка сложности паролей пользователей она будет производиться уже по регистрозависимой форме. Поэтому при вызове моего варианта это довольно легко реализовать при передаче в функцию вторым параметром выражения НЕ ПолучитьПроверкуСложностиПаролейПользователей(), а в Вашем случае пользователь может в систему войти, а при проверке получить ошибку и долго удивляться.

О какой публикации речь?
о моей, которую Вы и комментируете...
8. Vlad Bill (Bad_Developer) 06.02.15 13:43
А кто нибуть разбирался как формируется запись пароля подключения к СУБД в файле srvribrg.lst
По идеи механизм формирования должен быть похож.
Пример из файла:

{6fe8ec41-e16b-422b-9073-cb214248591a,"Torg","","PostgreSQL","dell2900","torgovlya","postgres","X4zp8HCS6WwSInfaP1n6vX+DnyVU0Hj6RwkD8poAcCE=","CrSQLDB=Y;DB=torg;DBMS=PostgreSQL;DBSrvr=dell2900;DBUID=postgres;Locale=ru_RU;Ref=torg;SLev=0;Srvr=dell2900;SUsr=",0,
{0,00010101000000,00010101000000,"","",""},0},
9. Константин Хрипков (mbreaker) 09.02.15 10:41
(8) Bad_Developer,
По идеи механизм формирования должен быть похож
нет, не должен. Потому что здесь пароль шифруется, а не хэшируется. Разница между между этими понятиями проста: в первом случае исходный пароль можно восстановить (дешифровать) обратным алгоритмом, в то время как получение хэша во втором случае - это односторонний процесс и единственный способ выхода на исходный пароль - это "брутфорс" со сравнением результата шифрования.
10. Сергѣй Батанов (baton_pk) 31.03.15 18:12
Это ж до меня тут дошло неожиданно, что если первый и второй хеши совпадают, то это с высоченной долей вероятности говорит о том, что пароль цифровой. Вот дырень-то...
11. Константин Хрипков (mbreaker) 01.04.15 07:53
(10) baton_pk, ну допустим "дырень" не в платформе 1С, а в голове администратора системы, т.к. в параметрах информационной базы есть настройка "Проверка сложности паролей пользователей", при установке которой система не допустит использования "цифрового пароля".
12. Сергѣй Батанов (baton_pk) 03.04.15 08:45
(11) mbreaker,
позволю себе не согласиться :) мы админим магазины через DameWare и чтобы избежать головной боли с разницей раскладок на локальном компе и на удалённом компе, используем длинный цифровой пароль для админа.
13. Константин Хрипков (mbreaker) 06.04.15 07:23
(12) baton_pk, я не совсем понял, с чем же высказано несогласие?
перевожу "мы в угоду удобству отказались от общепринятых рекомендаций по формированию политике безопасности, но стараемся компенсировать это длиной пароля".
Ну, да ладно, спор о том, у кого длиннее цифровой пароль, здесь немного неуместен.
Только вопрос "дырени", как я его понял, относился к проверке установки паролей пользователями, а не админами. Какой смысл админу в системе самому себе заводить ограничения?
14. Сергѣй Батанов (baton_pk) 07.04.15 13:01
(13) mbreaker,
Поясню. Пароли мы админим из главного узла - они выгружаются в XML-ку. Соответственно, знающий человек может разобрать XML-ку, выдрать отттуда сохраняемое значение пароля и проанализировать его.
Хотя это из разряда фантастики всё-таки...
15. don (donyab) 18.03.16 18:50
(10) baton_pk,
ИЛИ ВСЕ КАПСОМ НАБРАНО)
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа