CryptDB要进行数据加密,需要实现具体的加密算法,然后使用加密层类型来进行封装。如果用户想在其上实现新的功能,一方面需要实现加密算法,一方面要添加加密层以及其他相关辅助结构。本文介绍这两者之间的一些接口设计,方便大家基于现有代码做实验。
加密算法
CryptDB使用了AES,OPE,blowfish,Pailliar,Search算法,用到了openssl以及NTL库,相关代码全部位于crypto目录下。这里主要关注其对外的接口,忽略算法的实现步骤。要实现新的算法,需要使用类似的方法定义接口并做内部实现。
几种算法接口介绍
blowfish
blowfish算法实现位于crypto/blowfish.hh中。相关代码如下:
class blowfish {
public:
blowfish(const std::string &key) {
BF_set_key(&k, key.size(), (const uint8_t*) key.data());
}
uint64_t encrypt(uint64_t pt) const {
uint64_t ct;
block_encrypt(&pt, &ct);
return ct;
}
uint64_t decrypt(uint64_t ct) const {
uint64_t pt;
block_decrypt(&ct, &pt);
return pt;
}
static const size_t blocksize = 8;
private:
BF_KEY k;
};
可以看到,要使用blowfish,首先要有密钥key来完成初始化类,然后分别使用encrypt和decrypt函数来实现加解密。算法处理的数据类型是uint64_t。
AES
CryptDB使用了两种AES的模式,其加解密相关的函数如下:
string
encrypt_AES_CBC(const string &ptext, const AES_KEY * enckey, string salt, bool dopad);
string
decrypt_AES_CBC(const string &ctext, const AES_KEY * deckey, string salt, bool dounpad);
string
encrypt_AES_CMC(const string &ptext, const AES_KEY * enckey, bool dopad);
string
decrypt_AES_CMC(const string &ctext, const AES_KEY * deckey, bool dopad);
可以看到,使用AES也是需要有密钥,通过encrypt和decrypt函数来完成加解密功能。处理的数据类型是string。
Pailliar
class Paillier_priv : public Paillier{
NTL::ZZ decrypt(const NTL::ZZ &ciphertext) const;
NTL::ZZ encrypt(const NTL::ZZ &plaintext);
NTL::ZZ add(const NTL::ZZ &c0, const NTL::ZZ &c1) const;
...
}
//使用举例
Paillier_priv * sk;
sk = new Paillier_priv();
ZZ pt0 = NTL::to_ZZ(1);
ZZ pt1 = NTL::to_ZZ(2);
const ZZ enc0 = sk->encrypt(pt0);
const ZZ dec0 = sk->decrypt(enc0);
const ZZ enc1 = sk->encrypt(pt1);
const ZZ dec1 = sk->decrypt(enc1);
assert((