Practice encryptedblobstore

一个基于Key/Value方式存取二进制数据的接口设计

  • 支持对单个条目进行加密
  • 增删改查方法
  • 辅助方法
  • 能够使用以下5种方式进行序列化
    • "SQLITE" Sqlite数据库
    • "XML" XML文件
    • "INI" INI文件
    • "DIR" 文件系统(目录结构)
    • "REG" Windows注册表
  • 支持拷贝
  • 完整的错误处理
  • 支持尽可能多的STL容器类型作为buf
  • 线程安全(可选)

C++

要求能通过不低于此测试用例强度的单元测试:http://git.koal.com/chenlei/blobstore/blob/master/blobstore/blobstore_test.cc

BlobStore 使用范例(C++伪代码)


XMLBlobStore xml_store("/path/to/xml");

char in_buf1[] = "11111111111111111111111111";
std::string in_buf2 = "222222222222222222222222";
std::vector<char> in_buf3(in_buf1, in_buf1 + sizeof(in_buf1));

// 设置明文
xml_store.setBlob("testkey1", in_buf1, sizeof(in_buf1));
xml_store.setBlob("testkey2", in_buf2);
xml_store.setBlob("testkey3", in_buf3)
// 以明文方式取出
char out_buf1[MAX];
std::string out_buf2;
std::vector<char> outbuf2;
xml_store.getBlob("testkey1", out_buf1, sizeof(out_buf1));
xml_store.getBlob("testkey2", out_buf2);
xml_store.getBlob("testkey2", out_buf3);

// 设置密文
xml_store.setEncryptedBlob("testkey1", passwd, in_buf1, sizeof(in_buf1));
xml_store.setBlob("testkey2", passwd, in_buf2, in_buf2.size());
// 以密文方式取出
char out_buf1[MAX];
std::string out_buf2;
xml_store.getBlob("testkey1", passwd, out_buf1, sizeof(out_buf1));
xml_store.getBlob("testkey2", passwd, out_buf2);

// 辅助方法
std::vector<std::string> keys = xml_store.keys();
bool has_key = xml_store.hasKey("testkey1");
bool is_encryped = xml_store.isEncrypted("testkey1");

// 序列化
xml_store.load(); // 从XML文件加载
xml_store.save(); // 序列化到XML文件

// 拷贝
XMLBlobStore new_xml_store("/path/to/new/xml");
blobstore_copy(new_xml_store, xml_store);
new_xml_store.save();

DBBlobStore db_store("/path/to/db");
blobstore_copy(db_store, xml_store);
db_store.save();

一个可能的接口设计示例(C++)

//一个基于Key/Value方式存取二进制数据的接口设计,支持对单个条目进行加密

/* 支持加密的二进制数据存储 */
class BlobStore {
public:
    /**
     *  构造器
     *  @param  type,支持以下4种
     *      "DIR"       文件系统(目录结构)
     *      "REG"       Windows注册表
     *      "SQLITE"        Sqlite数据库
     *      "XML"       XML文件
     *  @param  storePath,对应不同type的路径定义如下
     *      "DIR"       文件目录路径
     *      "REG"       Windows注册表路径
     *      "SQLITE"        Sqlite数据库文件路径
     *      "XML"       XML文件路径
     */
    static BlobStore createInstance(string type, string storePath);

    string getType();

    /* 持久化 */
    int load();
    int save();

    /* 将所有Key/Value复制到另一个Store(可以是不同类型的Store) */
    int copyTo(BlobStore &other);

public:
    /* 遍历与查找 */
    int size();                     //获取容量
    set<string> listAliases();      //获取名称列表
    boolean containsAlias(string alias);    //判断存在性
    boolean isEncrypted(string alias);      //判断条目是否加密
    string findAlias(const vector<BYTE>&);  //根据二进制内容查找名称

    /* 明文数据操作 */
    int getBlob(string alias, vector<BYTE> & );
    int setBlob(string alias, const vector<BYTE>& );

    /* 密文数据操作(固定使用SM4或AES256-CBC加密,密钥使用password的MD5摘要值) */
    int getEncryptedBlob(string alias, string entryPassword, vector<BYTE> &);
    int setEncryptedBlob(string alias, string entryPassword, const vector<BYTE>&);

    /* 删除 */
    int deleteBlob(string alias);
    int clearAll();
}

Java

要求使用JUNIT对以下所有接口进行单元测试(包括异常流)

BlobStore 使用范例(Java伪代码)


    IBlobStore xs = BlobStoreFactory.createInstance("XML", "/path/to/xml");

    String in1 = "11111111111111111111111111";
    byte[] in2 = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};

    String passwd = "abcdefgh";

    // 设置明文
    xs.setBlob("testkey1", in1);
    xs.setBlob("testkey2", in2);

    String out1 = xs.getBlobAsString("testkey1");
    byte[] out2 = xs.getBlob("testkey2");

    // 设置密文
    xs.setEncryptedBlob("testkey1", passwd, in1);
    xs.setEncryptedBlob("testkey2", passwd, in2);

    // 以密文方式取出
    out1 = xs.getEncryptedBlobAsString("testkey1", passwd);
    out2 = xs.getEncryptedBlob("testkey2", passwd);

    // 辅助方法
    String[] keys = xs.listAliases();
    boolean hasKey = xs.containsAlias("testkey1");
    boolean isEncrypted = xs.isEncrypted("testkey2");

    // 序列化
    xs.load(); // 从XML文件加载
    xs.save(); // 序列化到XML文件

    // 拷贝
    IBlobStore xs2 = BlobStore.createInstance("XML", "/path/to/new_xml");
    xs.copyTo(xs2);
    xs2.save();

    IBlobStore ds = BlobStore.createInstance("DB", "/path/to/test.db");
    xs.copyTo(xs2);
    xs2.save();

一个可能的接口设计示例(Java)

interface IBlobStore {
    public String getType();

    /* 持久化 */
    public int load();
    public int save();

    /* 将所有Key/Value复制到另一个Store(可以是不同类型的Store) */
    public int copyTo(IBlobStore other);

    /* 遍历与查找 */
    public int size();                              //获取容量
    public String[] listAliases();                  //获取名称列表
    public boolean containsAlias(String alias);     //判断存在性
    public boolean isEncrypted(String alias);       //判断条目是否加密
    public String findAlias(byte[] value);              //根据二进制内容查找名称

    /* 明文数据操作 */
    public int setBlob(String alias, String value);
    public int setBlob(String alias, byte[] value);
    public byte[] getBlob(String alias);
    public String getBlobAsString(String alias);

    /* 密文数据操作(固定使用SM4或AES256-CBC加密,密钥使用password的MD5摘要值) */
    public int setEncryptedBlob(String alias, String entryPassword, String value);
    public int setEncryptedBlob(String alias, String entryPassword, byte[] value);
    public byte[] getEncryptedBlob(String alias, String entryPassword);
    public String getEncryptedBlobAsString(String alias, String entryPassword);

    /* 删除 */
    int deleteBlob(String alias);
    int clearAll();
}

class BlobStoreFactory {

    /**
     *  构造器
     *  @param  type,支持以下4种
     *      "DIR"       文件系统(目录结构)
     *      "REG"       Windows注册表
     *      "SQLITE"        Sqlite数据库
     *      "XML"       XML文件
     *  @param  storePath,对应不同type的路径定义如下
     *      "DIR"       文件目录路径
     *      "REG"       Windows注册表路径
     *      "SQLITE"        Sqlite数据库文件路径
     *      "XML"       XML文件路径
     */
    static IBlobStore createInstance(String type, String storePath) {
        ...
    }
}

class XMLBlobStore implements IBlobStore {
    ...
}

class DbBlobStore implements IBlobStore {
    ...
}
原文地址:https://www.cnblogs.com/qiuxiangmuyu/p/6134467.html