我正在创建一个CakePHP Web应用程序。显然密码是用哈希存储的,但有没有办法安全地存储将被检索的其他字段的值?我不是在说任何像信用卡一样敏感的东西,而是存储SSN和工资。我不确定存储信息的标准是什么,或者CakePHP是否有帮助。我使用InnoDB作为引擎。
答案 0 :(得分:0)
我说的不是敏感的事情,但会存储SSN和薪金。
CakePHP可能不直接支持此功能,但是如果您使用CipherSweet,则不仅可以在存储敏感信息之前对其进行加密,还可以在SELECT查询中(间接)使用这些字段。
例如,您可以加密用户的SSN和薪水,然后维护以下各项的独立索引:
此外,CipherSweet仅使用authenticated encryption,密文为securely randomized。在引擎盖下,它goes out of its way to ensure each field and index has a unique key。
<?php
use ParagonIE\CipherSweet\Backend\FIPSCrypto;
use ParagonIE\CipherSweet\BlindIndex;
use ParagonIE\CipherSweet\CipherSweet;
use ParagonIE\CipherSweet\EncryptedRow;
use ParagonIE\CipherSweet\KeyProvider\StringProvider;
use ParagonIE\CipherSweet\Transformation\LastFourDigits;
$cipher = new CipherSweet(
new StringProvider(
str_repeat("\xff", 32)
),
new FIPSCrypto()
);
$ER = (new EncryptedRow($cipher, 'users'))
->addIntegerField('salary')
->addTextField('ssn')
->addBlindIndex(
'ssn',
new BlindIndex('ssn_idx', [], 32)
)
->addBlindIndex(
'salary',
new BlindIndex('salary_idx', [], 16)
)
->addBlindIndex(
'ssn',
new BlindIndex(
'ssn_last4_idx',
[new LastFourDigits()],
16
)
)
;
密文是随机的,但索引是静态的。让我们加密用户的记录(我们称她为爱丽丝)。
$plaintext = [
'username' => 'alice',
'ssn' => '123-456-7890',
'salary' => 135000
];
list($row, $indexes) = $ER->prepareRowForStorage($plaintext);
$decrypted = $ER->decryptRow($row);
var_dump($row, $indexes, $decrypted);
这将产生类似的内容:
array(3) {
["username"]=>
string(5) "alice"
["ssn"]=>
string(149) "fips:sZU-A5GvF0vrXFTuXJMoIjKrr3HAO83dSsfPXajlTkg7-ce9goff4TGsbnsmBje77USijlEp3xR0sDTo2gekZEtzoDaoNUbBcm57Va5DiFztHEV2QaREEzCdU-uV5MOg3dpxoxfq116ZRlMA"
["salary"]=>
string(145) "fips:hoSB4beTtcMbOum2RoPYE8PSagvCDoeGq2mjiONm_mj6A_wobXxrMjb_x_Z-u7oMVg2TvpzXbxdN7JP0XGm6ITwefMMF5Jhq7rbYjAX38SWcCYcYyryHmBr5WgVFOJM-bvhuhAOEi6o="
}
array(3) {
["ssn_idx"]=>
string(8) "3cc637b3"
["ssn_last4_idx"]=>
string(4) "bb0c"
["salary_idx"]=>
string(4) "5879"
}
array(3) {
["username"]=>
string(5) "alice"
["ssn"]=>
string(12) "123-456-7890"
["salary"]=>
int(135000)
}
如果您还要将此数据与另一位员工的记录(我们称他为Bob)进行比较,则会看到类似的索引:
$plaintext = [
'username' => 'bob',
'ssn' => '456-123-7890',
'salary' => 135001
];
您会看到类似的内容:
array(3) {
["username"]=>
string(3) "bob"
["ssn"]=>
string(149) "fips:yauOEc7jF529frr7BYf16N7WNDs0koRj5yX3RhyCVPacBWPr_G8KltBSjVkNobIu2sfeWeLFCRBr1p0VHoNCADd4PPcJa6IciKjU8-K5v7Znt93g-NNlhaMzPOLqE9UVob9YxKpMb-9ZEzcW"
["salary"]=>
string(145) "fips:X64DBCbralyoNuE2sZvK_HjkRhIdrnNbVY2qaHfM1s6YmMUjNnRHVS0mq_SYS3Vo982BL72RMumhtPLwa4MoewOD8ycgbLhRx74-CjyFXdqFbPkEoeLESCBu471O-19Dx-4JJVGROHM="
}
array(3) {
["ssn_idx"]=>
string(8) "6950e82d"
["ssn_last4_idx"]=>
string(4) "bb0c"
["salary_idx"]=>
string(4) "0287"
}
array(3) {
["username"]=>
string(3) "bob"
["ssn"]=>
string(12) "456-123-7890"
["salary"]=>
int(135001)
}
一些细节值得注意:
ssn_last4_idx
和Bob的ssn_last4_idx
完全相同(此键为bb0c
),因为应用了LastFourDigits
变换。ssn_idx
和salary_idx
)也不同。因此,如果您选择的查询如下所示:
"SELECT * FROM users WHERE ssn_last4_idx = ?"
["bb0c"]
...您将获得两行(一列给爱丽丝,一列给鲍勃),因为它们的SSN的后4位相同。
但是,如果要使用它,则改为:
"SELECT * FROM users WHERE ssn_last4_idx = ? AND salary_idx = ?"
["bb0c", "0287"]
您只会得到Bob。同样:
"SELECT * FROM users WHERE ssn_idx = ?"
["3cc637b3"]
...将唯一标识爱丽丝。
实施searchable encryption是一项艰巨的任务,但无需重新发明轮子。
CakePHP并未内置CipherSweet,但是没有理由不能在以后的版本中提出。