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
pip install encrypted-storage
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)
storage = EncryptedSwiftStorage(container='credit_card_data')
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 own
loadfunctions 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
EncryptedMongoDBStorageclass that would inherit from your
MongoDBStorageclass and the
class EncryptedMongoDBStorage(EncryptedSharedStorage, MongoDBStorage): def __init__(self, myarg): super(EncryptedMongoDBStorage, self).__init__(host)
- Your new storage backend
savefunction must always accept a
datain that order.
- Your new storage backend
loadfunction must always accept a
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)
- Follow Pep8.
- Write tests.
If there is a backend you want that is not here, write one and open a pull request.
Create docker images with docker-compose for the different backends for testing.