一、定义
目的是隐藏对真实数据块的访问,使得攻击者不能区分每一次访问是真实还是随机的。
是一种可以用来完全隐藏IO操作的数据访问模式的加密方案。访问模式是指IO操作访问文件的顺序、访问文件的频率、读写顺序等,当用户把数据存储在不可信的第三方时,即使数据是加密的,第三方仍能通过收集用户访问模式信息推断出用户隐私,在ORAM方案中,若两次访问序列长度相同,则其访问模式是相同的,使得第三方无法通过访问模式获取用户隐私。简单来说,ORAM将用户的一个文件访问请求转换成多个文件访问请求,从而模糊化用户访问文件的概率、模式等信息。目前ORAM研究较多的领域是云存储安全。
二、使用步骤
1.各种方案介绍
三、实现
在 ORAM 中,实现客户端查询服务器上按顺序排列的一组元素集合,并确保服务器无法知道具体查询了哪些位置的元素,可以通过以下步骤来实现。这个过程需要使用 ORAM 的核心特性,即隐藏访问模式,确保服务器不能通过访问模式推断出客户端查询了哪些位置的元素。
具体步骤
- 数据初始化:将数据分块并存储在服务器上,同时构建 ORAM 结构。
- 客户端查询:客户端输入多个位置值,希望获取这些位置上的元素。
- 路径访问和混淆:客户端通过 ORAM 机制访问数据,混淆路径,以隐藏实际的查询位置。
- 伪访问操作:引入伪访问操作,使得服务器无法区分真实访问和伪访问。
代码如下:
import random class ORAM: def __init__(self, num_blocks): self.num_blocks = num_blocks self.tree = [None] * (2 * num_blocks) # Binary tree structure for ORAM self.stash = [] self.position_map = {i: self.random_leaf() for i in range(num_blocks)} def random_leaf(self): # 随机生成一个叶节点 return random.randint(0, self.num_blocks - 1) def init_tree(self, data_blocks): for block_id, block_data in data_blocks.items(): path = self.position_map[block_id] self.write_path(path, [(block_id, block_data)]) def query_positions(self, positions): results = {} unique_paths = set() # 计算每个块的路径,并记录唯一路径 for pos in positions: path = self.position_map[pos] unique_paths.add(path) # 下载所有相关路径 path_blocks = {} for path in unique_paths: path_blocks[path] = self.download_path(path) # 查找每个位置的数据块 for pos in positions: path = self.position_map[pos] block_data = self.find_in_path_or_stash(pos, path_blocks[path]) results[pos] = block_data self.reassign_path(pos) # 写回所有路径 for path in unique_paths: self.write_path(path, path_blocks[path]) return results def download_path(self, path): # 模拟从服务器下载路径上的数据块 return self.tree[path] if self.tree[path] else [] def write_path(self, path, blocks): # 模拟将路径上的数据块写回服务器 self.tree[path] = blocks def find_in_path_or_stash(self, pos, path_blocks): for block in path_blocks: if block and block[0] == pos: return block[1] return None def reassign_path(self, pos): # 重新分配数据块的路径 self.position_map[pos] = self.random_leaf() # 示例数据 data_blocks = {i: f"data_{i}" for i in range(10)} oram = ORAM(num_blocks=10) oram.init_tree(data_blocks) # 客户端查询位置1, 3, 5上的元素 positions = [1, 3, 5] results = oram.query_positions(positions) print(results