我想将敏感信息(主要是密码)存储在 silverstripe 的数据对象中。数据需要加密存储在数据库中。如果我在模板中调用此字段,我需要解密数据。
但我不知道该怎么做。有人可以指出我正确的方向吗?
谢谢!
我想将敏感信息(主要是密码)存储在 silverstripe 的数据对象中。数据需要加密存储在数据库中。如果我在模板中调用此字段,我需要解密数据。
但我不知道该怎么做。有人可以指出我正确的方向吗?
谢谢!
您可以做的是创建一个Password
DataObject
与Member
对象具有一对多关系的Password
对象。您可以使用登录会员的 salt 和 2 路 php 加密功能来加密和解密密码。
此示例代码使用 php mcrypt 和成员 salt 来加密和解密密码。
密码类具有描述、url、用户名和密码。它包含一个使用给定密钥加密给定字符串的函数。它还包含一个解密函数,用于使用连接的成员 salt 解密存储的密码。
密码类
<?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 对象以与 Password 对象建立 has_many 关系:
MemberPasswordListExtension
<?php
class MemberPasswordListExtension extends DataExtension {
private static $has_many = array(
'Passwords' => 'Password'
);
}
这是在您的配置中添加扩展所必需的:
_config.php
...
Member::add_extension('Member', 'MemberPasswordListExtension');
...
以下是添加密码的表格。在提交时,我们使用成员 salt 和 Password 类中的 encrypt 函数对密码进行加密。
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();
}
...
在页面模板中,我们调用表单并遍历保存在此用户下的密码。我们显示用户名、加密密码和解密密码,只是为了向我们展示这是有效的:
Page.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
有关如何完成此操作的示例,请参阅中的各种类。在您自己的代码库(即 mysite/)中的某处实现 PasswordEncryptor_Custom.php 并重新实现所有功能。
请注意,这是非常不典型的,并且违背了安全的最佳实践。作为一般经验法则,您永远不应该向任何人提供明文密码。可逆密码加密本质上是不安全的,因为您实际上是将一个明文密码(用户的)替换为另一个(明文密钥)。使用不同的哈希值简单地重置密码总是更好的。