opaquedb/opaquedb

GitHub: opaquedb/opaquedb

基于全同态加密的抗量子分布式隐私数据库,支持在不泄露查询内容的前提下对加密数据执行 SQL 等值查询。

Stars: 1 | Forks: 0

OpaqueDB # OpaqueDB **在不泄露查询的情况下对加密数据执行 SQL。**

Documentation License C++20 Microsoft SEAL BFV Scheme gRPC

它是什么 · 快速开始 · 文档 · 用例 · 它不是什么 · 构建 · 集群 · 参考文献 · 许可证 · 捐赠

## 它是什么 OpaqueDB 处理针对数据的 SQL 查询,但不会知道您查询了什么。客户端使用自己的密钥对其要搜索的值进行加密。服务器在加密数据上评估匹配,并返回一个加密结果,只有客户端才能解密。操作员运行查询,但永远看不到查询值或密钥。 这是一个基于 Microsoft SEAL 和 BFV 方案构建的计算型私有信息检索(PIR)系统。其隐私保证非常明确: - 隐私依赖于 Ring-LWE,这是一种目前没有已知量子攻击的格假设。 - 它可以抵御半诚实操作员。服务器之间没有非串谋假设,因此整个集群是一个单一的信任域。 - 目前系统是 QueryPrivate(查询隐私)的:操作员永远无法得知查询值。DataPrivate(数据隐私)模式(即操作员也永远无法得知存储的数据)将在后续版本中发布。 部署单元是一个由相同节点组成的分片集群。分片将 PIR 所需的线性扫描分散到多台机器上执行。 有关其适用场景,从私有凭证检查到机密查询,请参阅文档网站上的[用例](https://docs.opaquedb.io/use-cases/)。 ### 匹配的工作原理 匹配键被二值展开为每条记录 `key_bits` 个 SIMD 插槽,许多记录被打包到一个密文的插槽中。对于每次查询,服务器在整个批次中并行计算: 1. `diff = query - key`,然后 `sq = diff * diff`,得到 `(q-k)^2`,在位匹配时为 0,不同时为 1; 2. `eq = 1 - sq`,即按位 XNOR,然后通过深度为 `log2(key_bits)` 的旋转乘树对每条记录的所有位进行 AND 操作,留下每条记录的相等指示符; 3. 明文掩码检索:将指示符与打包的 payload 相乘并求和,因此只有匹配记录的 payload 会被保留,外加一个加密的存在计数,这样无匹配的查询将返回空结果。 无论该批次包含多少条记录,此操作每批次仅需 `1 + log2(key_bits)` 次密文与密文相乘(这是 FHE 的主要开销),因此昂贵的乘法开销会被分摊到数千行数据上。参数是通过与 `examples/crypto_bench` 对比测量得出的:默认采用 `poly_modulus_degree` 16384(这是在噪声预算中容纳乘法深度所必需的)、349 位系数模数以及 `key_bits` 16(均可配置)。查询以单个密文的形式进行传输。 辅助 `INDEX` 列重用了这个完全相同的 pipeline。每个可搜索列的键在磁盘上的一条记录中并排打包,服务器提取出查询所指定的列,因此对索引的匹配与单键评估完全相同,没有额外的加密乘法开销。由于数据是按主键进行分片的,索引查询只需扇出到每个分片并对部分结果求和,这与键查询的路径相同。 ## 快速开始 构建二进制文件(参见[构建](#building)),然后声明表、加载 CSV、启动服务并运行私有查询。 使用 `CREATE TABLE` 声明 schema。只能有一列作为主 `KEY`(它是可搜索的,并对数据进行分片)。任何列也可以标记为 `INDEX` 使其也可搜索;其余的是有类型的 payload 列,它们会被返回但不参与匹配: ``` -- weather.sql CREATE TABLE weather ( id INT KEY, city TEXT INDEX, country TEXT INDEX, temperature INT, humidity INT, conditions TEXT INDEX ); ``` 查询会根据其 `WHERE` 指定的列进行匹配,因此可以通过 `id`、`city`、`country` 或 `conditions` 查找此表。`KEY` 或 `INDEX` 列必须是 `INT` 或 `TEXT`(不能是 `REAL`)。`INDEX` 列既作为搜索键又作为 payload 存储,因此它也会被返回;`KEY` 列是唯一的例外,它参与匹配但不返回。 CSV 的表头指定了列名: ``` id,city,country,temperature,humidity,conditions 1,Amsterdam,NL,18,72,Cloudy 2,Tokyo,JP,27,61,Clear ``` 加载它,启动一个节点,并按键查询。示例文件位于 `examples/` 中: 加载示例数据并启动节点(本地不安全开发模式): ``` opaquedb run --set auth.mode=none --set auth.enable_insecure=true & opaquedb load --schema examples/weather.sql --csv examples/weather.csv ``` 然后打开交互式 shell,通过任何可搜索的列(主 `KEY` 或任何 `INDEX`)运行私有查询: ``` $ opaquedb repl --schema examples/weather.sql OpaqueDB shell. \help for commands, \quit to exit. opaquedb(default)> SELECT city, temperature, conditions FROM weather WHERE id = 1 city=Amsterdam temperature=18 conditions=Cloudy opaquedb(default)> SELECT city, temperature FROM weather WHERE country = "JP" city=Tokyo temperature=27 opaquedb(default)> SELECT city, country FROM weather WHERE conditions = "Clear" LIMIT 5 city=Tokyo country=JP city=Santiago country=CL opaquedb(default)> SELECT country FROM weather WHERE city = "Atlantis" (no rows) opaquedb(default)> \quit ``` 无论您匹配哪一列,查询值都会被加密;在辅助 `INDEX` 上进行匹配,不会向操作员泄露更多信息,其加密往返过程也与在键上匹配完全相同。 一次性查询的工作方式相同,并会打印出解码后的行: ``` $ opaquedb query 'SELECT country, temperature, conditions FROM weather WHERE city = "Amsterdam"' \ --schema examples/weather.sql country=NL temperature=18 conditions=Cloudy ``` `"Amsterdam"` 在离开客户端之前就已加密。节点在加密状态下扫描每一行,并仅返回加密后的匹配项。 ### 多重匹配:LIMIT 和 OFFSET 一个可搜索的值可以匹配多行。默认值为 `LIMIT 1`,因此单纯的查询只会返回一行: ``` $ opaquedb query 'SELECT city, country, temperature FROM weather WHERE conditions = "Sunny"' \ --schema examples/weather.sql city=Nairobi country=KE temperature=24 ``` 添加 `LIMIT n` 可获取更多行。有两个城市的 `conditions = "Sunny"`,它们会在一次查询中一并返回: ``` $ opaquedb query 'SELECT city, country, temperature FROM weather WHERE conditions = "Sunny" LIMIT 5' \ --schema examples/weather.sql city=Nairobi country=KE temperature=24 city=Cairo country=EG temperature=33 ``` `OFFSET m` 可对匹配结果进行分页;行在多次查询中以稳定的顺序返回,因此 `LIMIT 1 OFFSET 1` 会返回第二个匹配项: ``` $ opaquedb query 'SELECT city, country FROM weather WHERE conditions = "Sunny" LIMIT 1 OFFSET 1' \ --schema examples/weather.sql city=Cairo country=EG ``` `LIMIT`/`OFFSET` 是公开的(它们不是机密,因此保留在明文模板中)并在客户端上执行。在底层,服务器将匹配项划分为 `crypto.result_buckets` 个存储桶(默认为 16),并将每个存储桶打包到一个结果中,因此 `LIMIT` 计算的是行数而不是存储桶插槽,且加密结果的大小不会随着 limit 的增加而增长。因此,单个值可以在一次往返中返回最多 `result_buckets` 行;增加 `result_buckets` 可获取更多结果。 ## 它不是什么 - 目前还不是一个完整的 SQL 引擎。当前评估的查询为 `SELECT FROM WHERE = :param`,其中 `` 是主 `KEY` 或任何 `INDEX` 列。每次查询只能有一个条件:其他运算符(IN、 LIKE、范围)以及通过 AND/OR 组合的条件已经可以解析,但尚未 在加密状态下进行评估。扩大引擎可以私密评估的运算符集合是我们正在进行的工作,因此预计随着时间的推移会支持更多 SQL 语法;[文档](https://docs.opaquedb.io)中记录了目前已支持的功能。 - 它不能跳过计算。PIR 需要进行完整的线性扫描。分片改善了延迟和吞吐量,但并不改变总计算量。 - 它不提供匿名性。身份验证属于访问控制:OpaqueDB 隐藏了查询 值,但从不隐藏查询者。服务器始终会知道是哪个经过身份验证的 主体发送了查询。您可以在 OpaqueDB 之上构建匿名身份验证(例如,在您的应用中使用匿名代理、Mix 层或匿名 凭证),但单靠数据库本身无法提供此功能。 客户端匿名性是您在数据库之上添加的额外一层,而不是它直接赋予您的属性。 - 它未附带客户端 SDK。gRPC 的 `.proto` 文件即为其通信契约。 `query` 子命令是一个开发测试客户端。 ## 功能 - 带有类型化列(int、real、text)的 `CREATE TABLE` schema,一个匹配键 `KEY`, 以及任意数量的用于搜索的辅助 `INDEX` 列 - 通过 Microsoft SEAL (BFV) 对加密数据进行私有相等性查找,支持在键或任何辅助索引上进行匹配 - 带有公开 `LIMIT`/`OFFSET` 的多行结果:一个匹配多行的值可以在一次往返中返回它们,且结果大小不会随 limit 增加 - 具有 etcd leader 选举、成员资格管理和查询扇出功能的分片集群 - 版本化的不可变 epoch:预写日志、原子发布、回滚 - Token、mTLS 和无身份验证模式,采用恒定时间 Token 比较 - 一个管理外观(AdminService)由 gRPC API 和 CLI 共享 - 统一日志记录到 stdout 或文件,支持 text 或 JSON 格式,可通过配置设定 - 通过 CMake target visibility 强制实现严格的分层 ## 构建 构建使用 CMake,并结合 Ninja 和 vcpkg(处于 manifest 模式)。依赖项由 `vcpkg.json` 中的 `builtin-baseline` 进行锁定。 常见任务通过 `Makefile` 执行,它是构建、测试、lint 和打包 命令的唯一事实来源(CI 会调用相同的 targets): ``` export VCPKG_ROOT=/opt/vcpkg # provided by the dev container make configure # first run builds dependencies via vcpkg make build make test ``` 运行 `make help` 以列出所有 target。实用的 target 包括:`make lint`(clang-format 和 clang-tidy)、`make package`(发布 `.deb` 和 `.tar.gz`),以及在 `configure`/`build` 时使用 `PRESET=release` 进行优化构建。 `.devcontainer/` 中的 dev container 提供了 C++20 工具链和 vcpkg。 首次配置较慢,因为 vcpkg 需要从源代码构建依赖项;随后的 构建将使用二进制缓存。 ## 多节点集群 `docker/` 中的 Docker Compose 设置会启动一个 etcd 和三个节点,它们会 选举出 leader,各自加载互不相交的分片,并回答跨分片的私有 查询: ``` docker compose -f docker/docker-compose.yml up --build -d docker compose -f docker/docker-compose.yml run --rm tools \ query 'SELECT country, temperature FROM weather WHERE city = "Santiago"' \ --target node1:50051 ``` 任何节点都可以作为目标;每个节点都会协调跨所有分片的查询。 ## 文档 完整的文档位于 **[docs.opaquedb.io](https://docs.opaquedb.io)**: - [用例](https://docs.opaquedb.io/use-cases/) — OpaqueDB 的适用场景以及 团队如何将其投入实际应用。 - 指南、SQL 和配置参考以及部署说明。 本 README 仅是简要介绍;文档网站是说明其用法的真正权威来源。 ## 参考文献 OpaqueDB 的私有匹配建立在同态加密技术的基础之上,这些技术用于 对加密数据进行查询,详见以下论文。如果您在 学术工作中使用了 OpaqueDB,请引用它: ``` @article{karacay2020intrusion, title = {Intrusion Detection Over Encrypted Network Data}, author = {Kara{\c{c}}ay, Leyli and Sava{\c{s}}, Erkay and Alptekin, Halit}, journal = {The Computer Journal}, volume = {63}, number = {4}, pages = {604--619}, year = {2020}, publisher = {Oxford University Press}, doi = {10.1093/comjnl/bxz111} } ``` ## 许可证 Apache-2.0。请参阅 [LICENSE](LICENSE)。 ## 捐赠 如果 OpaqueDB 对您有帮助,欢迎使用 Monero (XMR) 进行捐赠: ``` 87MykA3xCxzAEUR8G4bQdvG6rpcuM9F8rTudD95MUX2cMSCVZPHyD45hq5uyrujKoCcx8jeYWTXC6ASemZ22AepD4SsfKWu ```
标签:Bash脚本, C++, Python工具, 分布式, 同态加密, 后量子密码学, 数据库, 数据擦除, 请求拦截, 隐私计算