【问题标题】:Sorting encrypted PHP object对加密的 PHP 对象进行排序
【发布时间】:2021-03-16 13:51:19
【问题描述】:

我有一个用户表,我已经加密并存储在 MySQL 数据库中。

当拉出数据并通过选择输入控件将其添加到表单时,我希望能够按字母顺序对项目进行排序。

我正在对 foreach 循环的每次迭代中的项目进行解密。

<?php foreach ($data['crewData'] as $crew) : ?>
   <option value="<?php echo $inputCrew; ?>">
      <?php echo decryptData($crew->user_firstName).' '.decryptData($crew->user_lastName); ?>
   </option>
<?php endforeach; ?>

我知道我可以使用sort($variable); 对数组进行排序,但是$data['crewData'] 返回的数据是标准对象,如下面的 sn-p 所示...

array(38) {
  [0]=>
  object(stdClass)#18 (21) {
    ["user_id"]=>
    string(2) "20"
    ["user_firstName"]=>
    string(59) "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

我想按 user_firstName 字段排序。对于如何做到这一点,我唯一的想法是运行一个 foreach 循环解密数据,创建一个临时的非加密对象,然后将其呈现给选择。

到目前为止,我只有大约 50 个用户,所以开销并不算太糟糕,但是随着用户数量的增加,我可以看到这很痛苦??

走上面的路线这行得通吗?

$crewData = $this->userModel->getUserByType('Crew');
$array = [];
foreach ($crewData as $item) {
   $firstName = decryptData($item->user_firstName)  //decryptData() is my decryption function
   array_push($array, $firstName );
}
$arraySorted = sort($array);

【问题讨论】:

  • 在运行时解密每个单独的属性似乎有点尴尬。你能不能在你的表上创建一个视图来解密然后从视图中选择?
  • 或者将你的解密逻辑上移到你的模型中,这样当你得到一个模型数组时,它们已经被解密了。
  • To go the above route will this work? - 是的,这可行,但随着应用程序的增长,您可能会后悔走这条路。对表格的每次更改都会在 PHP(视图、控制器、模型等)中产生 n 个更改

标签: php


【解决方案1】:

我不太了解您的要求或设置,但一种选择是将您的解密逻辑移到您的数据库中。这实际上为您提供了更多的控制权和安全性,因为您可以将权限应用于who can run the decrypt functionwho can execute the users_decrypted view

这只是一些伪代码,但它看起来像。

// Create a function to do the decryption
CREATE FUNCTION decrypt (input VARCHAR) 
RETURNS VARCHAR

BEGIN

   DECLARE decrypted VARCHAR;

   SET decrypted = '';

   // your decryption logic

   RETURN decrypted;

END;

// Create your view which returns the decrypted values
CREATE VIEW users_decrypted AS

    SELECT first_name, last_name FROM (
        SELECT decrypt(first_name) as first_name
            , decrypt(last_name) as last_name
            , ...
        FROM users
    ) ORDER BY first_name;

然后在您的模型中,您将使用视图而不必担心解密实际数据。

<?php
$query = 'SELECT first_name, last_name FROM users_decrypted';
...

或者,如果您想将解密逻辑保留在 PHP 中,您可以将其全部移动到您的模型中,这样您的控制器和视图就不必处理它。您可以在这里进行分类。

IMO,这个解决方案更慢、更复杂,从长远来看需要更多的编码和维护。

class User extends Model
{
    public function getUsers()
    {
        $users = 'SELECT first_name, last_name,... FROM users';

        ...

        $listOfKeysToDecrypt = ['first_name', 'last_name', ...];

        // This actually modifies the array which may not be a good idea.
        // You could always create a new array instead.
        foreach ($user as $key => $value) {
            if (in_array($key, $listOfKeysToDecrypt)) {
                $user[$key] = decrypt($value);
            }
        }

        // $user is now decrypted so you can sort it
        usort($users, ...);

        return $users;
    }

}

【讨论】:

  • 感谢@waterloomatt - 我目前正在使用 libsodium 来加密/解密。我需要了解有关 MySQL 加密/解密的更多信息,但它是否与 libsodium 一样工作,我假设 MySQL 路由可能更安全,正如您在回答中提到的那样?
  • libsodium 是一个很棒的库,所以如果你想要的话,请继续使用它。我的建议是将您的加密/解密逻辑上移到您的模型中,这样您就不必处理控制器/视图中的各个属性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-05
  • 2016-08-27
  • 1970-01-01
  • 2011-10-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多