The idea is implementing only save(add/update) and delete, using the stores we already have today by just adding crypt / decrypt and scheduling Query (readWithFilter) for the next release

DataManager

public Store encryptedStore(String storeName, String passphrase) {
        // TODO Create a default passphrase-based KeyStore
        KeyStore keyStore = null;
        return encryptedStore(storeName, keyStore);
}

public Store encryptedStore(String storeName, KeyStore keyStore) {
        StoreConfig storeConfig = new StoreConfig();
        storeConfig.setType(StoreTypes.ENCRYPTED_MEMORY);
        return encryptedStore(storeName, storeConfig, keyStore);
}

public Store encryptedStore(String storeName, StoreConfig config, String passphrase) {
        // TODO Create a default passphrase-based KeyStore
        KeyStore keyStore = null;
        return encryptedStore(storeName, config, keyStore);
}

public Store encryptedStore(String storeName, StoreConfig config, KeyStore keyStore) {
        config.setKeyStore(keyStore);
        Store store = storeFactory.createStore(config);
        stores.put(storeName, store);
        return store;
}

EncryptedMemoryStore

public class EncryptedMemoryStore<T> implements Store<T> {

    private final MemoryStorage<T> memoryStorage;
    private final CryptoUtils<T> cryptoUtils;

    public EncryptedMemoryStore(IdGenerator idGenerator, KeyStore keyStore) {
        memoryStorage = new MemoryStorage(idGenerator);
        cryptoUtils = new CryptoUtils<T>(keyStore);
    }

    @Override
    public StoreType getType() {
        return StoreTypes.ENCRYPTED_MEMORY;
    }

    @Override
    public Collection<T> readAll() throws InvalidKeyException {
        Collection<T> encryptedCollection = memoryStorage.readAll();
        return cryptoUtils.decrypt(encryptedCollection);
    }

    @Override
    public T read(Serializable id) throws InvalidKeyException {
        T encryptedItem = memoryStorage.read(id);
        return cryptoUtils.decrypt(encryptedItem);
    }

    @Override
    public List<T> readWithFilter(ReadFilter filter) throws InvalidKeyException {
        List<T> encryptedList = memoryStorage.readWithFilter(filter);
        return cryptoUtils.decrypt(encryptedList);
    }

    @Override
    public void save(T item) {
        memoryStorage.save(cryptoUtils.encrypt(item));
    }

    @Override
    public void reset() {
        memoryStorage.reset();
    }

    @Override
    public void remove(Serializable id) {
        memoryStorage.remove(id);
    }

    @Override
    public boolean isEmpty() {
        return memoryStorage.isEmpty();
    }

}

CryptoUtils

Here is where the magic happens.


public class CryptoUtils<T> {

    private final KeyStore keyStore;

    public CryptoUtils(KeyStore keyStore) {
        this.keyStore = keyStore;
    }

    public Collection<T> decrypt(Collection<T> encryptedCollection) {
        List<T> decryptedList = new ArrayList<T>();
        for (T item : encryptedCollection) {
            decryptedList.add(decrypt(item));
        }
        return decryptedList;
    }

    public List<T> decrypt(List<T> encryptedList) {
        List<T> decryptedList = new ArrayList<T>();
        for (T item : encryptedList) {
            decryptedList.add(decrypt(item));
        }
        return decryptedList;
    }

    public T decrypt(T item) {
        // TODO Read all fields and decrypt
        return item;
    }

    public T encrypt(T item) {
        // TODO Read all fields and encrypt    
        return item;
    }

}