{ "info": { "author": "Dominik Leibenger", "author_email": "python-seccs@mails.dominik-leibenger.de", "bugtrack_url": null, "classifiers": [ "Development Status :: 2 - Pre-Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.5", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "==================================\nseccs --- the SECure Content Store\n==================================\n\n.. image:: https://travis-ci.org/netleibi/seccs.svg?branch=master\n :target: https://travis-ci.org/netleibi/seccs\n\n.. image:: https://badge.fury.io/py/seccs.svg\n :target: https://badge.fury.io/py/seccs\n\n.. image:: https://readthedocs.org/projects/seccs/badge/?version=latest\n :target: http://seccs.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status\n\nWhat it is\n----------\n\n`seccs` is a Python library that realizes a secure and efficient hash-table-like\ndata structure for contents on top of any existing key-value store as provided\nby, e.g., cloud storage providers.\n\nIt has been developed as part of the work [LS17]_ at CISPA, Saarland University.\n\nInstallation\n------------\n\n::\n\n $ pip install seccs\n\nIf you want to use AES-SIV encryption (you probably want!), you also need to install PyCrypto 2.7a1 which is not yet available in PyPI::\n\n\t$ pip install https://ftp.dlitz.net/pub/dlitz/crypto/pycrypto/pycrypto-2.7a1.tar.gz\n\nUsage and Overview\n------------------\n\n`seccs` is a Python implementation of `sec-cs`, a secure and efficient\nhash-table-like data structure for contents. It stores its data on top of any\nexisting database providing a key-value store interface. Thus, it is likewise\nusable with in-memory :code:`dict` objects, persistent databases like\n:code:`ZODB`, and many cloud storage providers.\n\nIts details are described in [LS17]_. In short, it is suitable for usage on\n`untrusted` cloud storage and has the following desirable properties:\n\n * Confidentiality:\n Stored contents are securely encrypted using a symmetric key.\n * Authenticity:\n `sec-cs` guarantees authenticity of all stored contents,\n irrespective of gurantees of the underlying database.\n * Storage Efficiency:\n Data deduplication strategies are applied to all stored contents. When\n storing new contents, overlapping parts of existing contents are\n automatically reused as to avoid redundancy.\n `sec-cs` is optimized for efficiency in presence of `many` similar\n contents: Storage costs of an n-bytes content that differs only slightly\n from an existing content are in O(log n).\n\nTypical Use Case\n^^^^^^^^^^^^^^^^\n\nIn the most-typical configuration, `sec-cs` chunks its contents hierarchically\nusing ML-CDC (see [LS17]_), usually relying on Rabin Karp hashes, and stores the\nresulting nodes in a `database` after applying AES-SIV-256 for encryption and\nauthentication. From a user perspective, we have to initialize a suitable\ndatabase object and a 32-bytes key first.\n\nDatabase and key setup:\n >>> database = dict()\n >>> import os\n >>> key = os.urandom(32)\n\nNote that we might want to store the database and the key at some persistent\nlocation in practice.\n\nNext, we need to create a `crypto wrapper` which is in charge of all the\ncryptographic operations. Depending on our security goals (e.g., whether\nencryption is required), we could choose any suitable wrapper from\n:code:`seccs.crypto_wrapper`. Afterwards, we can instantiate the data structure.\n\nChoice of `crypto wrapper` and instantiation of data structure:\n >>> import seccs\n >>> crypto_wrapper = seccs.crypto_wrapper.AES_SIV_256(key) # install PyCrypto>=2.7a1 to use AES-SIV\n >>> seccs = seccs.SecCSLite(256, database, crypto_wrapper) # 256 is the chunk size\n\n.. note::\n\n Internally, `sec-cs` splits contents into chunks, creates a tree of chunks\n for each of them and inserts each node separately into the `database`. The\n first parameter specifies the desired `average` size of nodes inserted into\n the database. As deduplication is performed at the chunk level, large chunk\n sizes decrease deduplication performance, but they also create less storage\n overhead when storing non-deduplicable contents as fewer nodes have to be\n stored.\n \n Performance is discussed in detail in [LS17]_. If high redundancy is\n expected, 256 bytes is typically a good compromise; otherwise, larger chunk\n sizes might be more suitable.\n\nWe can now insert contents...\n >>> content = b\"This is a test content.\"\n >>> digest = seccs.put_content(content)\n >>> repr(digest)\n '\\x08,f+\\xa74\\xdc\\x0f\\xe5Oo\\xcb;\\x83\\xb9T\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x17'\n\n...retrieve them...\n >>> seccs.get_content(digest)\n This is a test content.\n\n...and delete them as soon as they are not needed anymore:\n >>> seccs.delete_content(digest)\n\nStorage Efficiency\n^^^^^^^^^^^^^^^^^^\n\n`seccs` avoids redundancy in the `database` wherever possible, as gets clear\nin the following example.\n\nConsider this function for measuring the `database`'s current storage costs in bytes:\n >>> import sys\n >>> def dbsize(db):\n >>> return sum([sys.getsizeof(k) + sys.getsizeof(v) for (k, v) in db.items()])\n\nInitially, the database is empty:\n >>> dbsize(database)\n 0\n\nInsertion of a 1 MiB content clearly causes some storage costs:\n >>> content1 = os.urandom(1024*1024)\n >>> digest1 = seccs.put_content(content1)\n >>> dbsize(database)\n 1583030\n\nBut inserting the same content for a second time does not incur additional costs:\n >>> content2 = content1\n >>> digest2 = seccs.put_content(content2)\n >>> digest1 == digest2 # identical contents yield identical digests\n True\n >>> dbsize(database)\n 1583030\n\nClearly, the database grows if different contents are inserted. However, these\ncosts are low if inserted contents are similar to existing ones.\n\nOnly about 2.3 KiB are required to store another 1 MiB content with one byte changed:\n >>> content3 = b''.join([content1[:512*1024], b'x', content1[512*1024+1:]])\n >>> digest3 = seccs.put_content(content3)\n >>> dbsize(database)\n 1585395\n\nCosts are similar even if the identical parts are shifted...\n >>> content4 = b''.join([content1[:512*1024], b'xyz', content1[512*1024+1:]])\n >>> digest4 = seccs.put_content(content4)\n >>> dbsize(database)\n 1588010\n\n...and deduplication is also performed if a content consists of parts of different existing contents:\n >>> content5 = b''.join([content1, content3, content4])\n >>> digest5 = seccs.put_content(content5)\n >>> dbsize(database)\n 1591009\n\nIn the last example, the growth was about 3 KiB.\n\nFurthermore, storage space is reclaimed completely when contents are removed:\n >>> seccs.delete_content(digest5)\n >>> seccs.delete_content(digest4)\n >>> seccs.delete_content(digest3)\n >>> seccs.delete_content(digest2)\n >>> dbsize(database)\n 1583030\n >>> seccs.delete_content(digest1)\n >>> dbsize(database)\n 0\n\n.. note::\n\n Every :code:`seccs.delete_content` call undos eactly one\n :code:`seccs.put_content` call. Thus, even if the same content has been\n inserted twice, yielding only a single digest, it has to be deleted twice as\n well to get actually removed.\n\nTesting\n-------\n\n`seccs` uses tox for testing, so simply run:\n\n::\n\n $ tox\n\nReferences:\n .. [LS17] Dominik Leibenger and Christoph Sorge (2017). sec-cs: Getting the\n Most out of Untrusted Cloud Storage. In Proceedings of the 42nd IEEE\n Conference on Local Computer Networks (LCN 2017), 2017.\n (Preprint: `arXiv:1606.03368 `_)", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/netleibi/seccs", "keywords": "", "license": "Apache Software License", "maintainer": "", "maintainer_email": "", "name": "seccs", "package_url": "https://pypi.org/project/seccs/", "platform": "", "project_url": "https://pypi.org/project/seccs/", "project_urls": { "Homepage": "https://github.com/netleibi/seccs" }, "release_url": "https://pypi.org/project/seccs/0.0.5/", "requires_dist": null, "requires_python": "", "summary": "Secure Content Store", "version": "0.0.5" }, "last_serial": 3220556, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "bef69486603e3d0be19ada3a0e203fd7", "sha256": "29f2248fe83ce02d6dd4e50ab9220e9188f5ffe94ecf2a887bb6ac28950cd554" }, "downloads": -1, "filename": "seccs-0.0.1.zip", "has_sig": false, "md5_digest": "bef69486603e3d0be19ada3a0e203fd7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24369, "upload_time": "2016-06-10T16:29:04", "url": "https://files.pythonhosted.org/packages/ac/3b/1467f6f850505f9edee60a8ea8bb0574a8f2190d4cc06d4f9b8003623ea2/seccs-0.0.1.zip" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "a90ce73364a9d733cff703e0bb430708", "sha256": "c76cb23bb9ad7ce12d77f7340f678d42452503d1f53987b227a81668d13da2a6" }, "downloads": -1, "filename": "seccs-0.0.2.zip", "has_sig": false, "md5_digest": "a90ce73364a9d733cff703e0bb430708", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25062, "upload_time": "2016-06-11T00:15:55", "url": "https://files.pythonhosted.org/packages/a4/ab/26430ee8409cf6ab51f880784584aee3de126eee7c37600ca8584d55f32c/seccs-0.0.2.zip" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "8351d6afb8a85f26fdf7bdc6d6cea88c", "sha256": "211044304eef227d1b1ed690e58c6d1686ebfff982632e186df17c58324ce2f4" }, "downloads": -1, "filename": "seccs-0.0.3.tar.gz", "has_sig": false, "md5_digest": "8351d6afb8a85f26fdf7bdc6d6cea88c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20293, "upload_time": "2017-02-14T18:48:32", "url": "https://files.pythonhosted.org/packages/17/81/1e6c2daab80923b377705eab6bd3b2e4cab405be3ead4f386507e642ef8e/seccs-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "16f858a02d0109a863cf903f18412cb7", "sha256": "dacc16f240fdb3a63a7cd9899c8475f641e4d7b79f6241296f2ab7287f516c3b" }, "downloads": -1, "filename": "seccs-0.0.4.tar.gz", "has_sig": false, "md5_digest": "16f858a02d0109a863cf903f18412cb7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20437, "upload_time": "2017-04-05T15:00:24", "url": "https://files.pythonhosted.org/packages/2f/d0/83c1b7291c18dc4d8e6027e7312add262c7ee98cd62700e5dfdbaa1e4557/seccs-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "bb3747c5bc98a09ede3a8403b561997e", "sha256": "d85463b11243cfce64d0bfd31dacb1a89e7bfaaa5e84ee086a41255ab31b9ef0" }, "downloads": -1, "filename": "seccs-0.0.5.tar.gz", "has_sig": false, "md5_digest": "bb3747c5bc98a09ede3a8403b561997e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20559, "upload_time": "2017-10-02T22:08:47", "url": "https://files.pythonhosted.org/packages/cd/51/fb01fd827dd59026f3b2ceae5144016597d462c012f294ba5dc734447b29/seccs-0.0.5.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "bb3747c5bc98a09ede3a8403b561997e", "sha256": "d85463b11243cfce64d0bfd31dacb1a89e7bfaaa5e84ee086a41255ab31b9ef0" }, "downloads": -1, "filename": "seccs-0.0.5.tar.gz", "has_sig": false, "md5_digest": "bb3747c5bc98a09ede3a8403b561997e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20559, "upload_time": "2017-10-02T22:08:47", "url": "https://files.pythonhosted.org/packages/cd/51/fb01fd827dd59026f3b2ceae5144016597d462c012f294ba5dc734447b29/seccs-0.0.5.tar.gz" } ] }