跳至主要内容

CryptDB的安装与使用

一、CryptDB介绍

CryptDB是来自MIT的一个开源项目,它不是某种数据库,而是加密数据库查询技术的一种,可以在加密的数据库(目前支持MySQL)上进行简单的操作。正常说来,一个应用是直接连接数据库的,配置了CryptDB后,CryptDB作为应用和数据库的中间代理,以明文的方式与应用交互,以密文的方式与数据库交互。其原理示意图如下:
CryptDB原理图

CryptDB首次解决了实用性的问题,它将数据嵌套进多个加密层,每层使用不同的密钥,这些加密密钥与用户的密码有关,即便是数据库管理员也不能访问这些加密的数据,这也防止了因数据库泄露导致用户信息泄露的问题。虽然目前支持的SQL语句有限,还没有到真正投入使用的程度,但其性却非常出众。Google也根据CryptDB的设计开发了Encrypted BigQuery client
CryptDB官网的介绍如下:
Online applications are vulnerable to theft of sensitive information because adversaries can exploit software bugs to gain access to private data, and because curious or malicious administrators may capture and leak data. CryptDB is a system that provides practical and provable confidentiality in the face of these attacks for applications backed by SQL databases. It works by executing SQL queries over encrypted data using a collection of efficient SQL-aware encryption schemes. CryptDB can also chain encryption keys to user passwords, so that a data item can be decrypted only by using the password of one of the users with access to that data. As a result, a database administrator never gets access to decrypted data, and even if all servers are compromised, an adversary cannot decrypt the data of any user who is not logged in. An analysis of a trace of 126 million SQL queries from a production MySQL server shows that CryptDB can support operations over encrypted data for 99.5% of the 128,840 columns seen in the trace. Our evaluation shows that CryptDB has low overhead, reducing throughput by 14.5% for phpBB, a web forum application, and by 26% for queries from TPC-C, compared to unmodified MySQL. Chaining encryption keys to user passwords requires 11-13 unique schema annotations to secure more than 20 sensitive fields and 2-7 lines of source code changes for three multi-user web applications.

二、安装CryptDB

安装系统:Ubuntu 12.04/13.04/14.04 x64
注:gccMySQL可以事先安装,也可以在安装CryptDB时自动安装。如果不更改CryptDB的默认密码letmein,那么配置MySQLroot用户密码也要设置为letmein

1) 安装Git和ruby

安装git是为了获取官网的源码,又因为CryptDB的安装脚本使用ruby语言编写,因此也需要安装ruby
$ sudo apt-get install git ruby

2) 克隆CrpytDB代码

这里把CryptDB项目克隆到了用户主目录下,后续步骤中也安装到了这个目录。根据个人喜好,可以自定义安装目录。
$ git clone -b public git://g.csail.mit.edu/cryptdb

3) 安装CrpytDB

安装非常简单,执行安装脚本,按照提示,等待完成。
$ cd cryptdb
$ sudo ./scripts/install.rb .
如果安装过程中出现问题,请翻阅下文中的可能出现的问题一节。

4) 添加环境变量EDBDIR.bashrc

编辑用户主目录/home/yourname/下的.bashrc,把下面的代码添加到最后,注意把/full/path/to/cryptdb/替换为CryptDB的安装目录。后续步骤中出现的/path/to/cryptdb/也请注意替换。
export EDBDIR=/full/path/to/cryptdb/

三、CryptDB的使用

源码doc/README文档中介绍了CryptDB的三种使用方法,这里只介绍Proxy方法。其他两种分别是TestsShell方法,使用方法请参考CryptDB的说明文档。

1) 启用Proxy

MySQL使用本地3306端口,CryptDB使用本地3307端口,CryptDB把3307端口的数据处理后通过3306端口与MySQL交互。
打开Terminal(我们称其为Terminal 1),替换CryptDB路径,复制后按Shift + Insert粘贴到Terminal中并执行:
/path/to/cryptdb/bins/proxy-bin/bin/mysql-proxy  \
   --plugins=proxy --event-threads=4             \
   --max-open-files=1024                         \
   --proxy-lua-script=$EDBDIR/mysqlproxy/wrapper.lua \
   --proxy-address=127.0.0.1:3307                \
   --proxy-backend-addresses=localhost:3306
如果执行成功,Terminal 1中会显示:
2015-10-22 23:26:30: (critical) plugin proxy 0.8.4 started

2) 连接到CryptDB

接下来另外打开一个Terminal(我们称其为Terminal 2)连接到本机3307端口的CryptDB。如果想直连MySQL,使用默认的mysql -u root -p即可。
mysql -u root -pletmein -h 127.0.0.1 -P 3307
# 或者隐藏密码登录
mysql -u root -p -h 127.0.0.1 -P 3307
Enter password:
默认用户名密码:root/letmein,如果登陆出现问题,请确认MySQL root用户的密码与CryptDB的密码相同。

3) CryptDB使用演示

现在,Ubuntu中已经有两个Terminal了,一个启用3307端口代理的Terminal 1,另一个是与CryptDB建立连接的Terminal 2。以下在Terminal 2中查询、创建数据库表、增加记录、查询记录,可以看到Terminal 1中会有CryptDB对应的操作。
Terminal 2,查询数据库:
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| cryptdb_udf        |
| mysql              |
| performance_schema |
| remote_db          |
+--------------------+
5 rows in set (0.02 sec):
Terminal 1,CryptDB查询数据库结果:
QUERY: show databases    
NEW QUERY: show databases
Terminal 2,创建数据库:
mysql> create database test;
Query OK, 1 row affected (0.05 sec)
Terminal 1,CryptDB创建数据库结果:
QUERY: create database test    
NEW QUERY: create database `test`
ENCRYPTED RESULTS:
+
|
+
+
Terminal 2,打开刚创建的数据库:
mysql> use test;
Database changed
Terminal 1,CryptDB打开数据库结果:
QUERY: show tables    
NEW QUERY: show tables
ENCRYPTED RESULTS:
+--------------------+
|Tables_in_test      |
+--------------------+
+--------------------+
Terminal 2,新建数据库表:
mysql> create table users(id int(2) not null primary key auto_increment,username varchar(40),password varchar(40));
Query OK, 0 rows affected (0.08 sec)
Terminal 1,CryptDB新建数据库表结果:
QUERY: create table users(id int(2) not null primary key auto_increment,username varchar(40),password varchar(40))    
NEW QUERY: create table table_XOJUPFKJFH (MZJAQVYXMSoPLAIN INT(2) unsigned not null auto_increment, ZJPTNSDEPOoEq VARBINARY(80), UBPDDGBBFPoOrder BIGINT unsigned, cdb_saltOLGYFXFRJM BIGINT(8) unsigned, NCWFXJZAQOoEq VARBINARY(80), QKRGQVOTWToOrder BIGINT unsigned, cdb_saltUWACWHCBBL BIGINT(8) unsigned, PRIMARY KEY index_16383471738825684568 (MZJAQVYXMSoPLAIN)) AUTO_INCREMENT=0 ENGINE=InnoDB
ENCRYPTED RESULTS:
+
|
+
+
Terminal 2:表中增加记录:
mysql> insert into users(username,password) values("foo","123456");
Query OK, 1 row affected (0.05 sec)
Terminal 1,CryptDB增加记录结果:
QUERY: insert into users(username,password) values("foo","123456")    
NEW QUERY: insert into `test`.`table_XOJUPFKJFH` (`test`.`table_XOJUPFKJFH`.`ZJPTNSDEPOoEq`, `test`.`table_XOJUPFKJFH`.`UBPDDGBBFPoOrder`, `test`.`table_XOJUPFKJFH`.`cdb_saltOLGYFXFRJM`, `test`.`table_XOJUPFKJFH`.`NCWFXJZAQOoEq`, `test`.`table_XOJUPFKJFH`.`QKRGQVOTWToOrder`, `test`.`table_XOJUPFKJFH`.`cdb_saltUWACWHCBBL`, `test`.`table_XOJUPFKJFH`.`MZJAQVYXMSoPLAIN`) values ('?\Z??-;??|?m???]??\\pV??O?GP$?u???t???????????T??p', 6053682719380228167, 11367024404434184659, '?T?? r?????\nc??O$??R\n??bU?????o?*)FD??\n|?*?9????', 2215019363748817985, 12229882942316980603, '\'0\'')
ENCRYPTED RESULTS:
+
|
+
+
Terminal 2,查询表中的记录:
mysql> select * from users;
+------+----------+----------+
| id   | username | password |
+------+----------+----------+
| 1    | foo      | 123456   |
+------+----------+----------+
1 row in set (0.02 sec)
Terminal 1,CryptDB查询记录结果:
QUERY: select * from users    
NEW QUERY: select `test`.`table_XOJUPFKJFH`.`MZJAQVYXMSoPLAIN`,`test`.`table_XOJUPFKJFH`.`ZJPTNSDEPOoEq`,`test`.`table_XOJUPFKJFH`.`cdb_saltOLGYFXFRJM`,`test`.`table_XOJUPFKJFH`.`NCWFXJZAQOoEq`,`test`.`table_XOJUPFKJFH`.`cdb_saltUWACWHCBBL` from `test`.`table_XOJUPFKJFH`
ENCRYPTED RESULTS:
+--------------------+--------------------+--------------------+--------------------+--------------------+
|MZJAQVYXMSoPLAIN    |ZJPTNSDEPOoEq       |cdb_saltOLGYFXFRJM  |NCWFXJZAQOoEq       |cdb_saltUWACWHCBBL  |
+--------------------+--------------------+--------------------+--------------------+--------------------+
|1                   |????-;??|?m???]??\pV??O?GP$?u???t???????????T??p|11367024404434184659|?T?? r??????c??O$??R???bU?????o?*)FD???|?*?9????|12229882942316980603|
+--------------------+--------------------+--------------------+--------------------+--------------------+
从CryptDB对应的结果可以看出,不仅数据库中的记录是加密的,表中的字段也是加密的。另外,直连到3306端口的MySQL,也能看到test数据库和表中的内容是加密的。

四、修改CryptDB密码

根据不同运行CryptDB的方式,密码保存的文件有所不同,上一节中使用代理的方式开启CryptDB服务,这种方式的密码保存在cryptdb\mysqlproxy\wrapper.lua中。修改该文件,把默认的letmein替换为自己的密码。
os.getenv("CRYPTDB_PASS") or "letmein" # 替换letmein
PS:关于另外两种方式的说明
使用Tests方式运行CryptDB,修改:test/test_utils.hh
使用Shell方式运行CryptDB,修改:main/cdb_test.cc
修改完CryptDB的密码,别忘了修改MySQL的密码,这两者的密码要相同:
$ mysqladmin -u root -p password # 修改MySQL的密码
Enter password:                  # 输入当前密码
New password:                    # 输入新密码
Confirm new password:            # 再次输入新密码

五、重新编译CryptDB

如果修改了源码,在cryptdb目录中执行make就可以重新编译CryptDB。如果修改了UDFs,还需要以root权限执行make install

六、可能出现的问题

1) 安装时出错

错误描述:
/home/yourname/cryptdb/mysql-src/sql/sql_yacc.yy:30:23: error: ‘yythd’ was not declared in this scope
#define YYTHD ((THD *)yythd)
^
/home/yourname/cryptdb/mysql-src/sql/sql_yacc.yy:37:14: note: in expansion of macro ‘YYTHD’
#define Lex (YYTHD->lex)
^
/home/yourname/cryptdb/mysql-src/sql/sql_yacc.yy:14618:23: note: in expansion of macro ‘Lex’
LEX *lex= Lex;
^
make[2]: *** [sql/CMakeFiles/sql.dir/sql_yacc.cc.o] Error 1
make[1]: *** [sql/CMakeFiles/sql.dir/all] Error 2
make: *** [all] Error 2
./scripts/install.rb:176:in `pretty_execute': `make` failed (RuntimeError)
    from ./scripts/install.rb:169:in `>'
    from ./scripts/install.rb:135:in `fn'
    from ./scripts/install.rb:281:in `<main>'
原因:
对于出现的yythd错误,是因为安装CrpytDB时把bison自动更新到了最新版(bison 3 导致上述问题),需要去掉CryptDB安装脚本install.rb中的bison自动更新,手动安装bison 2
解决步骤:
(1) 去掉script/install.rb中的bison
打开install.rb,查找bison,可以看到bison位于apt-get中,说明安装时会自动更新bison。删除该位置的bison,保存install.rb
(2) 手动安装bison 2
wget http://launchpadlibrarian.net/140087283/libbison-dev_2.7.1.dfsg-1_amd64.deb
wget http://launchpadlibrarian.net/140087282/bison_2.7.1.dfsg-1_amd64.deb
dpkg -i libbison-dev_2.7.1.dfsg-1_amd64.deb
dpkg -i bison_2.7.1.dfsg-1_amd64.deb

2) 删除数据库出错

错误描述:
QUERY: select @@version_comment limit 1    
main/Connect.cc:112 (execute): mysql_query: Unknown database 'yourdroppedDB'
main/Connect.cc:113 (execute): on query: USE `yourdroppedDB `
mysql-proxy: main/rewrite_main.cc:126: std::map<std::basic_string<char>, int> collectTableNames(const string&, const std::unique_ptr<Connect>&): Assertion `c->execute("USE " + quoteText(db_name))' failed.
Aborted (core dumped)
原因:
如果使用3306端口的MySQL而不是通过CryptDB删除加密数据库,会导致CryptDB仍然查询已经被删除的数据库而出现上述问题。
解决办法:
删除cryptdb\shadow目录下的所有文件。

七、参考

评论

此博客中的热门博文

VMware Workstation 10安装Mac OS X Mountain Lion 10.8.5

关于原版OS X Mountain Lion 10.8.5 Mac OS X Mountain Lion 10.8.5作为Mountain Lion的最后一个稳定版本值得我们收藏。可能大家有所不知,10.8.5版本是分为两个Build的,一个是在2013年9月13日发布的 10.8.5 Build 12F37 ,另一个是2013年10月3日发布的 10.8.5 Build 12F45 。也就是说, 10.8.5 Build 12F45 才是Mountain Lion的最终版本。 OS X Mountain Lion的维基百科 不幸的是,网友们和论坛中分享的 OS X Mountain Lion 10.8.5 正式版 原版完整DMG安装镜像 大多数是Build 12F37版本(从发帖日期就可以看出来),网上搜索到的种子文件也是Build 12F37的种子。要想下载原版Build 12F45,可以搜索 OSX1085-12F45-ESD.dmg ,或者从这里下载: http://pan.baidu.com/s/1f68Vv 怎么知道下载了哪个版本? 通过文件的MD5等校验值来辨别。使用软件: Hash 或者 HashTab 。 OS X Mountain Lion 10.8.5 Build 12F37.dmg 信息如下: 大小: 4469250353 字节 MD5: 5568B4DDE00A64F765EF00858B538078 SHA1: ECF68C2119C71825839D2A58E0D619E9CCF7C026 CRC32: F4DFCE4D 从中提取出的InstallESD.dmg: MD5: 2C77151BE45C820B02A9ACE05434693D SHA1: 2919B519142E2119197BFFD678F15F603E84970F CRC32: A9DCAE18 OSX1085-12F45-ESD.dmg 信息如下: 大小: 4448808132 字节 MD5: 3FCEBFC81D00767D1ACEF1CB166F88CC SHA1: 98E52D0FC443940265780539A311833EE5814DDD CRC32: C82F14C1 从中提取出的InstallESD.dmg: 大小: 443...

为Github的Hexo博客启用SSL/TLS

CloudFlare的免费套餐提供了SSL,可以用它为我们独立域名的博客启用HTTPS。本文以 http://g2ex.me 为例。 主要步骤 注册CloudFlare,添加个人网站,获取CLoudFlare提供的 Nameservers ; 修改自己的域名提供商,把 站点的Nameservers 修改为 CloudFlare提供的Nameservers ; 等待CloudFlare添加的网站为激活状态,使用 https 打开个人网站; 修改网站模版,使 http 跳转到 https 。 详细步骤 一、注册CloudFlare 首先注册CloudFlare,注册后按照提示 Add Websites ,输入域名后点击 Begin Scan : 到达最后一步,会提示把自己网站的域名 Name Server 更换为: charles.ns.cloudflare.com ivy.ns.cloudflare.com 二、修改域名提供商的Nameservers 本站使用了Godaddy域名提供商,登录Godaddy,在域名的 SETTINGS 中,点击 Nameservers 下的 Manage : 勾选 Custom 并点击 ADD NAMESERVER ,添加上边CloudFlare给的两个Name Servers。 三、等待CloudFlare确认 稍等片刻(几分钟到十几分钟),在CloudFlare中点击 Recheck Nameservers ,可以看到网站已经处于激活状态了。 之后,便可以用 https://g2ex.me 访问站点了。 四、强制跳转 至此,必须手动输入 https 前缀才能访问加密的站点,要想在任何情况下都以加密方式访问网站,可以在网站模版的头中加入 http 到 https 的强制跳转。 以当前Hexo的 NexT主题 为例,打开 layout 目录下的 _layout.swig ,在 <head> 标签中加入以下代码,注意把 yoursite.com 替换为你的域名,这里为 g2ex.me 。 < script type = "text/javascri...

VMware9 安装Mac OS X 10.8

VMware Workstation 9.0.0下安装Mac OS X 10.8的经验总结: 1. 首先检查CPU是否支持虚拟化,使用到的软件是securable; 2. 安装完VMware后,需要给它装一个补丁,补丁是unlock-all-v110\windows\install.cmd,Win7下需要右键使用管理员身份运行; 3. 创建Mac OS X 虚拟机时,磁盘类型选择SCSI,使用单个文件存储虚拟磁盘,在CD/DVD设备的高级设置里,选择SCSI,SCSI 0:1; 4. 安装完Mac OS X,需要安装VMware Tool。如果你的VMware是完整版,那么去VMware的安装目录下找darwin.iso,在VMware里加载到Mac OS X 的CD/DVD中,否则只能去网上下载darwin.iso,但是网上下载的不能保证适用在VMware9上,可能会出现“darwin.iso无法识别”的错误; 5. 安装完VMware Tool千万不要重启,否则重启后容易花屏,这时安装VMware VGA Display驱动:VMsvga2_v1.2.4_OS_10.6-8.pkg,然后重启即可。 完整的图文安装过程: http://bbs.pcbeta.com/forum.php?mod=viewthread&tid=1130227