Encrypted Storage
Encrypted Storage helps with saving and loading encrypted data in various storage backends. It is implemented in a way to be able to add new backends easily by inheritance.
How it works
It does AES symetric encryption of a file, then asymetric RSA encryption on the key from the intial symetric encryption. These files are then saved in one of the various storage backends.
Currently implemented backends
- OpenStack Swift
- Redis
Installation
pip install encrypted-storage
Usage
from encrypted_storage import EncryptedRedisStorage
# Initialize storage.
storage = EncryptedRedisStorage(db_num=10)
# Encrypt and save data.
storage.save(filename, data, public_key)
# Decrypt and load data.
loaded_data = storage.load(filename, private_key)
Backends
OpenStackSwift
storage = EncryptedSwiftStorage(container='credit_card_data')
Redis
storage = EncryptedRedisStorage(db_num=10)
Creating New RSA Keys
You can use whatever method you like to create new keys. Just be sure the format is identical to the format of currently stored keys. I recommend using Pycrypto to generate new keys as the encryption and encryption is based off of this package. Watch for newlines.
from Crypto.PublicKey import RSA
rsa_obj = RSA.generate(1024)
private_key = rsa_obj.exportKey()
public_key = rsa_obj.publickey().exportKey()
Adding New Storage Backends
To create new storage backends simply follow these 2 steps:
- Create a class that inherits from
BaseSharedStorage
. This will do the saving and loading from your storage. If you wanted to create a new MongoDB storage backend you would write your ownMongoDBStorage
class withsave
andload
functions specific to MongoDB.
class MongoDBStorage(BaseSharedStorage):
def __init__(self, host):
# You can do init stuff here, like initializing your `pymongo.MongoClient`.
self.mongo = pymongo.MongoClient(host)
def save(self, filename, key, data):
# do the MongoDB saving
def load(self, filename):
# do the MongoDB loading
- Write a new
EncryptedMongoDBStorage
class that would inherit from yourMongoDBStorage
class and theEncryptedSharedStorage
class.
class EncryptedMongoDBStorage(EncryptedSharedStorage, MongoDBStorage):
def __init__(self, myarg):
super(EncryptedMongoDBStorage, self).__init__(host)
Rules
- Your new storage backend
save
function must always accept afilename
,key
, anddata
in that order. - Your new storage backend
load
function must always accept afilename
.
Encryption w/o Storage
Sometimes you just want to encrypt stuff.
from encrypted_storage import AESCypher, EncryptedSharedStorage
data = "These aren't the droids you are looking for."
# For symetrical encryption
encrypt_cypher = AESCipher()
encrypted = encrypt_cypher.encrypt(data)
key = encrypt_cypher.key
decrypt_cypher = AESCipher(key=key)
decrypted = decrypt_cypher.decrypt(encrypted)
# For asymetrical encryption
cypher = EncryptedSharedStorage()
encrypted_key, encrypted_data = cypher.asym_encryption(data, public_key)
decrypted_data = cypher.asym_decryption(encrypted_key, encrypted_data, private_key)
Contributing
- Follow Pep8.
- Write tests.
If there is a backend you want that is not here, write one and open a pull request.
TODO
Create docker images with docker-compose for the different backends for testing.