Я хочу хранить конфиденциальную информацию (в основном пароли) в объекте data в silverstripe. Данные необходимо хранить в зашифрованном виде в базе данных. Если я вызываю это поле в своем шаблоне, мне нужны данные, дешифрованные.
Но я не знаю, как это сделать. Может ли кто-нибудь указать мне в правильном направлении?
Спасибо!
Что вы можете сделать, так это создать объект DataObject
с объектом Member
имеющим отношение «один к многим» к объекту « Password
. Вы можете использовать соль зарегистрированного участника с помощью двухсторонней функции шифрования php для шифрования и дешифрования пароля.
Этот примерный код использует php mcrypt с солью-членом для шифрования и дешифрования пароля.
Класс пароля содержит описание, URL-адрес, имя пользователя и пароль. Он содержит функцию для шифрования данной строки с использованием заданного ключа. Он также содержит функцию дешифрования для дешифрования сохраненного пароля с использованием связанной соли членов.
Класс пароля
<?php class Password extends DataObject { static $db = array ( 'Description' => 'Text', 'URL' => 'Text', 'Username' => 'Text', 'Password' => 'Text' ); static $has_one = array ( 'Member' => 'Member' ); public function decryptedPassword() { return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($this->Member()->Salt), base64_decode($this->Password), MCRYPT_MODE_CBC, md5(md5($this->Member()->Salt))), "\0"); } public function encryptPassword($key, $password) { return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $password, MCRYPT_MODE_CBC, md5(md5($key)))); } }
Нам нужно расширить объект Member, чтобы иметь отношение has_many с объектом Password:
MemberPasswordListExtension
<?php class MemberPasswordListExtension extends DataExtension { private static $has_many = array( 'Passwords' => 'Password' ); }
Это необходимо в вашей конфигурации, чтобы добавить расширение:
_config.php
... Member::add_extension('Member', 'MemberPasswordListExtension'); ...
Ниже приведена форма для добавления пароля. При представлении мы шифруем пароль, используя соль члена и функцию шифрования из класса Password.
Page_Controller
... public function AddPasswordForm() { // Create fields $fields = new FieldList( new TextField('Description'), new TextField('URL'), new TextField('Username'), new TextField('Password') ); // Create actions $actions = new FieldList( new FormAction('AddPassword', 'Submit') ); return new Form($this, 'AddPasswordForm', $fields, $actions); } public function AddPassword($data, $form) { if($member = Member::currentUser()) { $password = new Password(); $form->saveInto($password); $password->MemberID = $member->ID; $password->Password = $password->encryptPassword($member->Salt, $password->Password); $password->write(); } return $this->redirectBack(); } ...
В шаблоне страницы мы вызываем форму и просматриваем пароли, сохраненные под этим пользователем. Мы показываем имя пользователя, зашифрованный пароль и расшифрованный пароль, чтобы показать нам, что это сработало:
Шаблон страницы.ss
... <% if $CurrentMember %> $AddPasswordForm <% end_if %> <% with $CurrentMember %> <h3>Passwords</h3> <% if $Passwords %> <ul> <% loop $Passwords %> <li>$Username $Password $DecryptedPassword</li> <% end_loop %> </ul> <% else %> <p>No passwords saved</p> <% end_if %> <% end_with %> ...
Это должно дать вам основу для того, что вы хотите сделать, и вы сможете изменить его на свои нужды.
Метод шифрования был взят из этого ответа stackoverflow: простейшее двухстороннее шифрование с использованием PHP
Вы можете легко заменить другой метод шифрования / дешифрования остальной частью этого кода по своему усмотрению.
По умолчанию Silverstripe 3.x хранит пароли с необратимым соленым хешем, используя Blowfish. Вы можете писать разные классы PasswordEncryptor для обработки других действий. См. Различные классы в framework/security/PasswordEncryptor.php
для примеров того, как это делается. Внедрите PasswordEncryptor_Custom.php где-нибудь в своей собственной базе кода (т. Е. Mysite /) и повторно реализуйте все функции.
Обратите внимание, что это очень нетипично и идет вразрез с лучшими практиками безопасности. Как правило, вы никогда не должны делать пароли открытого текста доступными кому-либо, периоду. Реверсивное шифрование паролей по своей сути небезопасно, так как вы фактически заменяете один пароль открытого текста (пользователя) другим (открытым текстовым ключом). Всегда лучше просто сбросить пароль с помощью другого хеша.