經緯度屬於連續數值型數據,業務常需「矩形/圓形範圍查詢」(如「查詢某半徑內的門店」)。加密後若失去順序性或空間關係,將無法直接用索引範圍掃描。
| 方案 | 原理 | 能否範圍查詢 | 安全性 | 適用場景 |
|---|---|---|---|---|
| 順序保持加密 (OPE) | 密文保持明文大小順序 | ✅ 支持 BETWEEN | 中等(洩露順序) | 單維度範圍查詢 |
| 空間填充曲線 (Z-order / Hilbert) | 將 2D 經緯度映射為 1D 有序編碼 | ✅ 近似矩形查詢 | 高(無順序洩露) | 地理圍欄、鄰近搜索 |
| 同態加密 (FHE) | 密文上直接計算 | ✅ 任意計算 | 極高 | 極高安全需求,性能極差 |
| 分表/分庫 + 應用層解密 | 按粗略網格分表,查詢時解密過濾 | ✅ 全精度查詢 | 高 | 數據量大、查詢頻率低 |
| 只存密文,查詢時全量解密 | 應用層遍歷解密過濾 | ❌ 無索引 | 高 | 數據量極小(<1萬) |
// 將 (lat, lon) 縮放為整數
long latInt = (long)((lat + 90) * 1e6);
long lonInt = (long)((lon + 180) * 1e6);
// 交織位元生成 Z-order 值
long morton = interleaveBits(latInt, lonInt);
// 加密存儲 morton(可選 AES)
String encrypted = AES_encrypt(String.valueOf(morton));
查詢矩形 [latMin, latMax] × [lonMin, lonMax] → 計算覆蓋的 Z-order 區間集合(通常分解為 1~N 個連續區間) → SQL WHERE morton BETWEEN ? AND ? → 應用層二次精確過濾。
morton 列建立 B+ 樹索引。Google CryptDB、Microsoft Always Encrypted)。