跳至主要内容

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目录下的所有文件。

七、参考

评论

此博客中的热门博文

网盘端到端加密 Cryptomator

1. Crytomator 是什么 Cryptomator 是一款开源的文件加密工具,它支持在本地硬盘上创建多个加密仓库,这些加密仓库以文件卷(硬盘卷)的形式挂载到系统目录中,存放到文件卷中的文件都会自动加密。 如果把加密仓库的目录放到网盘的同步目录下,配合如 iCloud、Dropbox、OneDrive、坚果云 等云盘使用,就能达到端到端加密同步的效果。 2. 同类工具对比 同类的文件加密工具除 Cryptomator 之外,还有 gocryptfs、encfs 等。其中 Cryptomator 使用 Java 开发,而且提供了 macOS、Windows、Linux、iOS 和 Android 上个 GUI 版本,从易用性上来说体验最佳。 gocryptfs v1.7 encfs v1.9.5 ecryptfs v4.19.0 cryptomator v1.4.6 securefs v0.8.3 CryFS v0.10.0 First release 2015 ( ref ) 2003 ( ref ) 2006 ( ref ) 2014 ( ref ) 2015 ( ref ) 2015 ( ref ) Language Go C++ C Java C++ C++ License MIT ( ref ) LGPLv3 / GPLv3 ( ref ) GPLv2 GPLv3 ( ref ) MIT ( ref ) LGPLv3 ( ref ) Development hotspot Austria USA USA (RedHat) Germany China Germany Lifecycle Active Maintenance Active ( ref ) Active Active Active File interface FUSE FUSE In-kernel filesystem FUSE/WebDAV FUSE FUSE Platforms Linux, macOS, 3rd-party Windows port,3rd-party Android port Linux, macOS, 3rd-par

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

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