С развитием информационных технологий все больше растет потребность в средствах криптографической защиты информации, одним из которых является шифрование информации. В данной статье рассмотрим пример шифрования текстовой информации с применением пароля на ISBL. В этом нам поможет объект IEncrypter, предназначенный для шифрования и дешифрования данных.
// Создать объект для шифрования
EncryptObj: ICrypto = CreateObject('SBRte.SBCrypto')
Encrypter: IEncrypter = EncryptObj.Encrypter
По умолчанию используется модуль шифрования Standard Encryption с GUID {B1B27433-D685-47F8-8500-CF9525407145}. Передаем текст и пароль для шифрования, вызываем метод Encrypt. После шифрования в свойство CryptContent записываются зашифрованные данные.
Encrypter.PluginName = '{B1B27433-D685-47F8-8500-CF9525407145}'
Encrypter.Content = 'Текстовая информация для шифрования'
Encrypter.Password = 'Пароль'
Encrypter.Encrypt
// Получить зашифрованные данные
EncryptData = Encrypter.CryptContent
В результате получим зашифрованную текстовую информацию.
Для дешифрования следует вызвать метод Decrypt объекта IEncrypter. Предварительно требуется задать в свойстве CryptContent зашифрованные данные, указать плагин шифрования и пароль. Для дешифрования данных, заданные в свойстве CryptContent, в свойстве Password следует указывать то же значение пароля, с помощью которого были зашифрованы исходные данные.
// Дешифрование данных
EncryptObj: ICrypto = CreateObject('SBRte.SBCrypto')
Encrypter: IEncrypter = EncryptObj.Encrypter
Encrypter.PluginName = '{B1B27433-D685-47F8-8500-CF9525407145}'
Encrypter.CryptContent = 'Зашифрованные данные'
Encrypter.Password = 'Пароль'
Encrypter.Decrypt
// Получение исходных данных
Result = Encrypter.Content
Encrypter = nil
EncryptObj = nil
Вышеописанные методы шифрования/дешифрования могут быть использованы, например, в прикладных методах справочников, выполняющих прикладную логику по шифрованию/дешифрованию текстовой информации по паролю. При этом, сам пароль может быть зашит как в самом коде, так и вычисляться на основе определенных реквизитов справочника. Данный способ не позволит ограничить доступ к зашифрованным данным прикладному разработчику, т.к. разработчик имеет доступ к алгоритму шифрования и, соответственно, к способу определения пароля для шифрования. Тем не менее, данный способ шифрования/дешифрования позволит ограничить доступ обычному пользователю.
Следует помнить о безопасности используемого пароля. Пароль не стоит в открытую показывать (хардкодить) в вычислениях, а также получать в переменные, так как запуск отладчика на рабочем месте пользователя приведет к его компрометации.
Мне кажется вы усложняете, для ограничения пользователей хватит и простеньких операций:
Ну и раз пошла такая пьянка:
1. Создаем Реквизиты:
2. Создаем Действие "OnExecute_ЗадатьПароль"
3. Создаем Действие "OnExecute_Дешифровать"
4. Вносим строки в Форму-карточки-Показ:
Готово. Теперь выводим поля и кнопки на Форму карточки:
Тестируем:
Жмем "Задать Пароль"
Сохраняем. Закрываем. Открываем вновь:
Пробуем ввести пароль "12345" и дешифровать:
Теперь вводим "123456":
Работа выполнена!
Тарас, если хранить пароль в строковом реквизите карточки документа, то любой пользователь сможет его увидеть, воспользовавшись поиском документов и выведя нужный реквизит в список отображаемых колонок (начиная с версии системы 5.5 или 5.6, точно не помню). Поэтому нужно либо использовать реквизит с типом "текст", либо использовать табличный раздел - такие в окне поиска не отображаются (по крайней мере, пока =))
Вы правы - забить это в таблицу и можно спать спокойно.
Наталья, а какой алгоритм шифрования используется в вашем примере? Насколько оно взломостоек и для чего его можно применять?
Тарас, я очень надеюсь что вы не применяете такое решение в продакшене, ведь с точки зрения безопасности оно смысла не имеет. Вы закрываете реквизит с паролем только из отображения (CanGUIRead), и если тянуть его из АПИ то все данные будут доступны, а значит имея права хотя бы на чтение справочника, злоумышленник может вытянуть все пароли. Даже если спрячете в табличные разделы.
Вообще пароли хранить не стоит. Если хотите зашифровать или расшифровать какой то кусок данных - предложите пользователю ввести пароль. После расшифровки переменную с паролем лучше вычистить. Если пароль будет неверный, то просто расшифрованный текст будет кривой. Ну или, если нужно реально проверить правильность пароля, шифруйте им какой то большой заранее известный текст и проверяйте. Правда, это сильно снизит безопасность шифра.
Андрей, упаси Господь использовать столь примитивное решение для реальной работы! Нет, это решение не более чем ограничение от некоторых пользователей и не далее. У нас есть некоторые процессы, где есть данные не для общего круга лиц и сделано это было скорее как "игрушка" для тех, кто считает, что данные по переписке читают все кому не лень.
Тарас, тогда и шифровать смысла нет. Заодно и процессор с памятью не занимать лишний раз. Ну или чтобы не совсем "светиться" - XOR еще никто не отменял. Шутка конечно.
А вообще вводить пользователей в заблуждение это плохо. Они же думают что у них все защищено паролем и никто больше прочитать информацию не сможет. А это не так.
По поводу кейса "читают все кому не лень" - интересное решение. Ведь человек, который шифровал данные может забыть пароль, уволиться, заболеть, или уйти в отпуск. Да и что делать, если данные нужно смотреть нескольким людям? Передавать пароль? Но тут опять проблема - пароль нельзя забрать обратно. А значит и доступ к информации нельзя отозвать.
Поэтому, может быть лучше сделать не через шифрование, а через права доступа? Выделить необходимые данные в отдельный справочник, на который ограничить права доступа только нужным людям. Права доступа в этом случае помогут не потерять доступ к информации, позволят вести контроль доступа и осуществлять аудит - кто в какое время получал доступ к записи справочника.
По поводу алгоритма шифрования раскопал сам, может кому интересно. Согласно справке используется 3DES.
Андрей Посаженников, ну я с этого и начал:
Object.Requisites('LongString').CanGUIWrite = FALSE // Блокируем от изменений! Object.Requisites("LongString2").CanGUIRead = FALSE // Скрываем из виду!
Это легко активируется простым вычислением пользователей по Ролям/группам/полномочиям.
CurrentUser = ServiceFactory.GetUserByName(Application.Connection.UserName) Admin = ServiceFactory.GetGroupMembers(ServiceFactory.GetGroupByName('Administrators')).Find(CurrentUser) //////////////////////////////// FinDirectorRole = ServiceFactory.GetRoleMembers(ServiceFactory.GetRoleByName('ФинДиректор'); NIL) IsFinDirector = FinDirectorRole.Find(CurrentUser) /////////////////////////////// CurrentUser.UserType = utAdministrator
И как правило этого достаточно. Но опять же, уже вы написали, что особо хитрожелтые пользователи могут вывести в список перечень параметров и тут уже надо исхитряться.
Можно заморочиться и написать простенький алгоритм реального шифрования текста, как самый дешевый пример - шифр Цезаря (посимвольное смещение), модифицированный на цикличное смещение. Но это уже из области "Программирование для паранойиков".
Авторизуйтесь, чтобы написать комментарий