Store sensitiv data in Silverstripe 3.1

筅森魡賤 提交于 2019-12-08 08:43:11

问题


I want to store sensitive informations (mainly passwords) in a dataobject in silverstripe. The Data need to be stored crypted in the database. If i call this field in my template, I need the data decrypted.

But I don't know how to do this. Can someone point me in the right direction?

Thx!


回答1:


What you could do is create a Password DataObject with the Member object having a one to many relationship to the Password object. You can use the salt of the logged in Member with a 2 way php encrypt function to encrypt and decrypt a password.

This example code uses php mcrypt with the member salt to encrypt and decrypt the password.

The password class has a description, a url, username, and password. It contains a function to encrypt a given string using a given key. It also contains a decrypt function to decrypt the stored password using the connected member salt.

Password class

<?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))));
    }

}

We need to extend the Member object to have a has_many relationship with the Password object:

MemberPasswordListExtension

<?php
class MemberPasswordListExtension extends DataExtension {

    private static $has_many = array(
        'Passwords' => 'Password'
    );
}

This is needed in your config to add the extension:

_config.php

...
Member::add_extension('Member', 'MemberPasswordListExtension');
...

The following is a form to add a password. On submission we encrypt the password using the member salt and the encrypt function from the Password class.

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();
}

...

In the page template we call the Form and loop through the passwords saved under this user. We display the username, the encrypted password and the decrypted password, just to show us this has worked:

Page.ss template

...

<% 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 %>

...

This should give you a base for what you want to do, and you should be able to change it to your needs.

The encryption method was taken from this stackoverflow answer: Simplest two-way encryption using PHP

You could easily substitute a different encrypt/decrypt method with the rest of this code as you desire.




回答2:


By default, Silverstripe 3.x stores passwords with an irreversible salted hash using Blowfish. You can write different PasswordEncryptor classes to handle other behaviours. See the various classes in framework/security/PasswordEncryptor.php for examples of how this is done. Implement PasswordEncryptor_Custom.php somewhere in your own codebase (i.e. mysite/) and re-implement all of the functions.

Note that this is very atypical and goes against best practices for security. As a general rule of thumb, you should never make plaintext passwords available to anybody, period. Reversible password encryption is inherently insecure, as you're effectively replacing one plaintext password (the user's) with another (a plaintext key). It is always better to simply reset the password with a different hash.



来源:https://stackoverflow.com/questions/19079073/store-sensitiv-data-in-silverstripe-3-1

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!