PHP 项目隐私集合求交 (PSI) 实现方案
PSI(Private Set Intersection)允许双方在不泄露各自数据内容的情况下,找到集合的交集,以下是几种主流实现方案:

基于哈希和布隆过滤器(简单但非严格安全)
<?php
class SimplePSI {
private $salt;
public function __construct($salt = null) {
$this->salt = $salt ?? bin2hex(random_bytes(16));
}
// 哈希并求交
public function intersect($setA, $setB) {
$hashedA = array_map([$this, 'hashItem'], $setA);
$hashedB = array_map([$this, 'hashItem'], $setB);
$intersection = array_intersect($hashedA, $hashedB);
// 还原交集(需要双方都公开哈希值)
return array_keys(array_intersect($hashedA, $hashedB));
}
private function hashItem($item) {
return hash_hmac('sha256', $item, $this->salt);
}
}
// 使用示例
$psi = new SimplePSI();
$setA = ['user1@email.com', 'user2@email.com', 'user3@email.com'];
$setB = ['user2@email.com', 'user4@email.com', 'user5@email.com'];
$common = $psi->intersect($setA, $setB);
print_r($common); // ['user2@email.com']
基于OPRF(Oblivious Pseudo-Random Function)
<?php
require 'vendor/autoload.php';
use Mdanter\Ecc\EccFactory;
use Mdanter\Ecc\Crypto\Key\PrivateKeyInterface;
class OPRFPSI {
private $serverPrivateKey;
private $generator;
public function __construct() {
$adapter = EccFactory::getAdapter();
$this->generator = EccFactory::getSecgCurves()->generator256k1();
$this->serverPrivateKey = $this->generator->createPrivateKey();
}
// 服务器端:接收盲化值并签名
public function serverEvaluate(array $blindedValues): array {
$results = [];
foreach ($blindedValues as $blinded) {
$point = $this->generator->getPublicKeyFrom($blinded['x'], $blinded['y']);
$result = $point->mul($this->serverPrivateKey->getSecret());
$results[] = [
'x' => $result->getX(),
'y' => $result->getY()
];
}
return $results;
}
// 客户端:盲化元素并计算
public function clientEvaluate(array $data, array $serverResults): array {
$hashes = [];
foreach ($data as $i => $item) {
// 去盲化
$unblinded = $this->unblind($serverResults[$i], $this->clientRandomness[$i]);
$hashes[] = hash('sha256', gmp_strval($unblinded->getX()) . $item);
}
return $hashes;
}
}
基于OT(Oblivious Transfer)的实现
<?php
class OTBasedPSI {
// 使用Naor-Pinkas OT协议
public function otExtension(array $receiverInput, array $senderSet) {
$commonElements = [];
// 实现1-out-of-2 OT
foreach ($receiverInput as $item) {
$choiceBit = $this->hashToBit($item);
// Bob(接收方)获得一个消息
$received = $this->obliviousTransfer(
$item,
$choiceBit,
$senderSet
);
if ($received === $item) {
$commonElements[] = $item;
}
}
return $commonElements;
}
private function hashToBit($item) {
return hexdec(substr(hash('sha256', $item), 0, 1)) % 2;
}
private function obliviousTransfer($choice, $bit, $senderSet) {
// 简化实现,实际应使用密码学安全协议
return $senderSet[$bit] ?? null;
}
}
使用PHP扩展 - libPSI包装
<?php
// 假设有一个C扩展包装了libPSI
class LibPSIWrapper {
private $psiInstance;
public function __construct(int $role) {
// role: 0 = client, 1 = server
$this->psiInstance = new PSI($role);
}
public function setup(int $numItems) {
$this->psiInstance->setup($numItems);
}
public function addItems(array $items) {
foreach ($items as $item) {
$this->psiInstance->addItem($item);
}
}
public function getIntersection(): array {
$result = [];
$this->psiInstance->computeIntersection(function($item) use (&$result) {
$result[] = $item;
});
return $result;
}
}
完整示例:Web API实现
<?php
// PSIEndpoint.php
class PSIEndpoint {
private $redis;
private $psiServer;
public function __construct() {
$this->redis = new Redis();
$this->redis->connect('127.0.0.1', 6379);
$this->psiServer = new SimplePSI();
}
public function handleRequest() {
$action = $_POST['action'] ?? '';
switch ($action) {
case 'client_submit':
return $this->clientSubmit();
case 'server_submit':
return $this->serverSubmit();
case 'compute':
return $this->computeIntersection();
default:
throw new Exception('Invalid action');
}
}
private function clientSubmit() {
$sessionId = bin2hex(random_bytes(16));
$data = json_decode($_POST['data'], true);
// 存储客户端数据(盲化后)
$blindedData = array_map(function($item) {
return hash('sha256', $item . $this->getSalt());
}, $data);
$this->redis->setex("psi:client:{$sessionId}", 3600, json_encode($blindedData));
return json_encode(['session_id' => $sessionId]);
}
private function serverSubmit() {
$sessionId = $_POST['session_id'];
$data = json_decode($_POST['data'], true);
$blindedData = array_map(function($item) {
return hash('sha256', $item . $this->getSalt());
}, $data);
$this->redis->setex("psi:server:{$sessionId}", 3600, json_encode($blindedData));
return json_encode(['status' => 'ok']);
}
private function computeIntersection() {
$sessionId = $_POST['session_id'];
$clientData = json_decode($this->redis->get("psi:client:{$sessionId}"), true);
$serverData = json_decode($this->redis->get("psi:server:{$sessionId}"), true);
$commonHashes = array_intersect($clientData, $serverData);
return json_encode([
'intersection_count' => count($commonHashes),
'intersection_hashes' => array_values($commonHashes)
]);
}
private function getSalt() {
return "YOUR_SECURE_SALT";
}
}
性能优化与最佳实践
<?php
class OptimizedPSI {
// 使用批量处理提高性能
public function batchIntersect(array $clientSets, array $serverSet) {
$results = [];
// 1. 使用布隆过滤器预处理服务端数据
$bloom = new BloomFilter(1024, 3); // 1024 bits, 3 hash functions
foreach ($serverSet as $item) {
$bloom->add($item);
}
// 2. 快速过滤客户端数据
foreach ($clientSets as $clientId => $clientSet) {
$candidates = [];
foreach ($clientSet as $item) {
if ($bloom->has($item)) {
$candidates[] = $item;
}
}
// 3. 精确匹配
$exactMatch = array_intersect($candidates, $serverSet);
$results[$clientId] = $exactMatch;
}
return $results;
}
// 内存优化 - 处理大数据集
public function streamIntersection($clientStream, $serverSet) {
$hashedServer = array_map('sha256', $serverSet);
$serverHashSet = array_flip($hashedServer);
$intersection = [];
foreach ($clientStream as $item) {
$hash = hash('sha256', $item);
if (isset($serverHashSet[$hash])) {
$intersection[] = $item;
}
}
return $intersection;
}
}
安装与部署建议
-
生产环境要求:
- PHP 7.4+ 或 8.0+
- OpenSSL 扩展
- GMP 或 BCMath 扩展(用于大数运算)
- 建议使用 PHP FFI 调用 C 库
-
性能考虑:
- 小数据集(<10k):使用哈希+布隆过滤器方案
- 中等数据集(10k-100k):使用OPRF方案
- 大数据集(>100k):使用OT扩展或专用C库
-
安全注意事项:
- 始终使用 HTTPS 传输
- 使用安全的随机数生成器
- 实施速率限制防止暴力攻击
- 定期更换加密密钥
实现提供了不同安全级别和性能特征的PSI方案,你可以根据具体需求选择合适的实现,对于生产环境,建议使用经过审计的密码学库,如libPSI或emp-toolkit的PHP绑定。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播