跳至主要内容

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...

Android 电视折腾记

要从 BBC 放出的几段《 Planet Earth II 》说起,突发奇想地打算在小米电视上看 YouTube 视频,电视的系统基于 Android 5.1,最终通过 Kodi + Youtube 插件成功实现目的。 0x00 介绍 Kodi 原名 XBMC,是一个开源跨平台的多媒体播放平台,支持视频、音乐、图片、直播、本地和在线媒体、网络服务等等。Kodi 最让人称奇的是它众多的插件,通过对应的插件,网络上的各种资源就可以完美地在 Kodi 中播放。 不过,在国内,要想观看 YouTube,还要考虑的一个问题是让电视自动翻墙。 这里以小米电视为例,当然也可以是其他 Android 电视,也可以是各种盒子。 0x01 让电视科学上网 有以下选择(前提是你有一台海外 VPS,搭建了 Shadowsocks 服务端,或者是配置了 VPN): 家用路由器翻墙。目前用的是小米路由器,需要刷开发版 ROM 获取 root 权限,才能安装 Shadowsocks 客户端实现自动翻墙,比较麻烦;现在小米 WiFi App 可以设置 智能 VPN ,支持 选择地址限流 和 选择设备限流 ,如果选择电视限流的话,电视相当于是全局 VPN 了。 不想折腾路由器的,可以用一台局域网电脑作为家庭代理,安装上 Shadowsocks 和 Privoxy(支持局域网的 SOCKS/http/https 代理)。按照这种思路最好弄个树莓派做家庭代理。 电视上安装翻墙 App,可选 Shadowsocks 和 Postern。 这里选择在电视安装 Postern App 。最主要原因是 Postern 的自动翻墙配置利用了 GEOIP 库可以精准地实现「国内流量直连,国外流量走代理」。Shadowsocks 设置里因为用 8.8.8.8 DNS(或其他) 去解析域名,国内的某些提供了海外加速的服务就会被解析到国外 IP 上,反而更慢了。另外,Postern 还能在配置里过滤广告。 具体的过程: 下载 Postern App https://github.com/postern-overwal/postern-stuff 下载自动翻墙配置文件 https://github.com/postern-overwal/postern-stuff/b...