安全内容存储
seccs的Python项目详细描述
它是什么
seccs是一个python库,它实现了一个安全高效的哈希表 提供的任何现有密钥值存储库顶部的内容的数据结构 例如,云存储提供商。
它是作为萨尔大学CISPA工作的一部分开发的。
安装
$ pip install seccs
如果你想使用AES-SIV加密(你可能想要!),您还需要安装pycrypto 2.7a1,但pypi中尚未提供它:
$ pip install https://ftp.dlitz.net/pub/dlitz/crypto/pycrypto/pycrypto-2.7a1.tar.gz
用法和概述
sec cs是seccs的python实现,安全高效
内容的哈希表式数据结构。它将数据存储在
现有数据库提供一个键值存储接口。因此,它也是
可用于内存中的dict
对象,如
ZODB
,以及许多云存储提供商。
其详细信息在[LS17]中描述。总之,它适合在 不受信任的云存储,并具有以下理想的属性:
- Confidentiality:
- Stored contents are securely encrypted using a symmetric key.
- Authenticity:
- sec-cs guarantees authenticity of all stored contents, irrespective of gurantees of the underlying database.
- Storage Efficiency:
- Data deduplication strategies are applied to all stored contents. When storing new contents, overlapping parts of existing contents are automatically reused as to avoid redundancy. sec-cs is optimized for efficiency in presence of many similar contents: Storage costs of an n-bytes content that differs only slightly from an existing content are in O(log n).
典型用例
在最典型的配置中,sec cs按层次对其内容进行分块 使用ml-cdc(参见[LS17]),通常依赖rabin karp散列,并存储 应用AES-SIV-256加密和 身份验证。从用户的角度来看,我们必须初始化一个合适的 首先是数据库对象和32字节的密钥。
- 数据库和密钥设置:
>>> database = dict() >>> import os >>> key = os.urandom(32)
注意,我们可能希望将数据库和密钥存储在 实际位置。
接下来,我们需要创建一个加密包装器,它负责
加密操作。取决于我们的安全目标(例如
加密是必需的),我们可以从中选择任何合适的包装
seccs.crypto_wrapper
。然后,我们可以实例化数据结构。
- 加密包装器的选择和数据结构的实例化:
>>> import seccs >>> crypto_wrapper = seccs.crypto_wrapper.AES_SIV_256(key) # install PyCrypto>=2.7a1 to use AES-SIV >>> seccs = seccs.SecCSLite(256, database, crypto_wrapper) # 256 is the chunk size
注意
在内部,sec cs将内容分成块,创建一个块树 并将每个节点分别插入到数据库中。这个 第一个参数指定插入到 数据库。由于重复数据消除是在数据块级别执行的,因此大数据块 大小会降低重复数据消除性能,但也会减少存储空间 将不可重复数据消除的内容存储为较少的节点时的开销 存储。
性能将在[LS17]中详细讨论。如果高冗余是 预计256字节通常是一个很好的折衷方案;否则,较大的块 尺寸可能更合适。
- 我们现在可以插入内容…
>>> content = b"This is a test content." >>> digest = seccs.put_content(content) >>> repr(digest) '\x08,f+\xa74\xdc\x0f\xe5Oo\xcb;\x83\xb9T\x00\x00\x00\x00\x00\x00\x00\x17'
- …检索它们…
>>> seccs.get_content(digest) This is a test content.
- …不需要时立即删除:
>>> seccs.delete_content(digest)
储存效率
seccs尽可能避免数据库中的冗余 在下面的例子中。
- 考虑使用此函数测量数据库当前的存储成本(字节):
>>> import sys >>> def dbsize(db): >>> return sum([sys.getsizeof(k) + sys.getsizeof(v) for (k, v) in db.items()])
- 最初,数据库为空:
>>> dbsize(database) 0
- 插入1 mib内容显然会导致一些存储成本:
>>> content1 = os.urandom(1024*1024) >>> digest1 = seccs.put_content(content1) >>> dbsize(database) 1583030
- 但第二次插入相同内容不会产生额外费用:
>>> content2 = content1 >>> digest2 = seccs.put_content(content2) >>> digest1 == digest2 # identical contents yield identical digests True >>> dbsize(database) 1583030
显然,如果插入了不同的内容,数据库就会增长。然而,这些 如果插入的内容与现有的内容相似,则成本较低。
- 只需要大约2.3 kib就可以存储另一个1 mib内容,并更改一个字节:
>>> content3 = b''.join([content1[:512*1024], b'x', content1[512*1024+1:]]) >>> digest3 = seccs.put_content(content3) >>> dbsize(database) 1585395
- 即使相同的零件发生移位,成本也相似…
- ^{pr 13页}$ 如果内容由不同的部分内容组成:DE/DD>,则重复删除。
>>> content5 = b''.join([content1, content3, content4]) >>> digest5 = seccs.put_content(content5) >>> dbsize(database) 1591009
在上一个例子中,增长约为3kib。
- 此外,当内容被删除时,存储空间被完全回收:
>>> seccs.delete_content(digest5) >>> seccs.delete_content(digest4) >>> seccs.delete_content(digest3) >>> seccs.delete_content(digest2) >>> dbsize(database) 1583030 >>> seccs.delete_content(digest1) >>> dbsize(database) 0
注意
每一个seccs.delete_content
调用都会撤销一个
seccs.put_content
呼叫。因此,即使相同的内容
插入两次,只产生一个摘要,必须删除两次
好吧,真的要搬走了。
测试
seccs使用tox进行测试,因此只需运行:
$ tox
- 参考文献:
[LS17] (1, 2, 3, 4) Dominik Leibenger and Christoph Sorge (2017). sec-cs: Getting the Most out of Untrusted Cloud Storage. In Proceedings of the 42nd IEEE Conference on Local Computer Networks (LCN 2017), 2017. (Preprint: arXiv:1606.03368)