查看CipherSweet。这是一个获得许可的开源库,可在 PHP 中提供可搜索的加密。
它的实现与Ebbe's answer相似,但有更多警告:
- CipherSweet 自动处理密钥拆分,through a well-defined protocol。
- CipherSweet 支持多种功能盲索引(明文转换的截断散列)以方便高级搜索。
此外,API 相对简单:
<?php
use ParagonIE\CipherSweet\BlindIndex;
use ParagonIE\CipherSweet\CipherSweet;
use ParagonIE\CipherSweet\CompoundIndex;
use ParagonIE\CipherSweet\EncryptedRow;
use ParagonIE\CipherSweet\Transformation\LastFourDigits;
/** @var CipherSweet $engine */
// Define two fields (one text, one boolean) that will be encrypted
$encryptedRow = (new EncryptedRow($engine, 'contacts'))
->addTextField('ssn')
->addBooleanField('hivstatus');
// Add a normal Blind Index on one field:
$encryptedRow->addBlindIndex(
'ssn',
new BlindIndex(
'contact_ssn_last_four',
[new LastFourDigits()],
32 // 32 bits = 4 bytes
)
);
// Create/add a compound blind index on multiple fields:
$encryptedRow->addCompoundIndex(
(
new CompoundIndex(
'contact_ssnlast4_hivstatus',
['ssn', 'hivstatus'],
32, // 32 bits = 4 bytes
true // fast hash
)
)->addTransform('ssn', new LastFourDigits())
);
实例化和配置对象后,您可以像这样插入行:
<?php
/* continuing from previous snippet... */
list($encrypted, $indexes) = $encryptedRow->prepareRowForStorage([
'extraneous' => true,
'ssn' => '123-45-6789',
'hivstatus' => false
]);
$encrypted['contact_ssnlast4_hivstatus'] = $indexes['contact_ssnlast4_hivstatus'];
$dbh->insert('contacts', $encrypted);
然后从数据库中检索行就像在 SELECT 查询中使用盲索引一样简单:
<?php
/* continuing from previous snippet... */
$lookup = $encryptedRow->getBlindIndex(
'contact_ssnlast4_hivstatus',
['ssn' => '123-45-6789', 'hivstatus' => true]
);
$results = $dbh->search('contacts', ['contact_ssnlast4_hivstatus' => $lookup]);
foreach ($results as $result) {
$decrypted = $encryptedRow->decrypt($result);
}
CipherSweet 目前在 PHP 和 Node.js 中实现,其他 Java、C#、Rust 和 Python 实现即将推出。