CryptDB代码分析1-lua与加密库

之前的文章 ”CryptDB原理概述“ 介绍了CryptDB的基本原理,接下来从代码的角度介绍其实现原理。本文首先关注mysql-proxy的lua脚本与CryptDB加密库的交互过程。

前期准备

在进行源码阅读和调试之前,首先需要进行CryptDB的安装。 之前已经对CryptDB在ubuntu 16.04上的安装做过介绍。也可以使用我在github上共享的项目:https://github.com/yiwenshao/Practical-Cryptdb,里面对原始的安装脚本做了小改,在ubuntu16.04只要执行INSTALL.sh 就可以完成全部的安装工作。

安装完成以后,首先执行如下的命令:

mkdir shadow
mysql-proxy --defaults-file=./mysql-proxy.cnf --proxy-lua-script=wrapper.lua

启动mysql-proxy[1],然后就可以通过MySQL的客户端连接mysql-proxy来完成数据库操作。 所有SQL语句首先经过mysql-proxy的加密处理, 然后转发给MySQL服务器。 对于MySQL服务器的返回结果, 也是先转发给mysql-proxy, 经过解密处理以后返回给客户端。

mysql-proxy通过lua脚本调用CryptDB的加密库来完成SQL语句的加密操作,而上面建立的shadow目录则是为了保存一个embedded模式的MySQL数据库, 里面存储了密钥以及加密洋葱的结构的等相关信息。

所以,接下来,我们先从lua脚本的入口出发,看一个SQL语句在加密过程中会经过哪些模块。

mysql-proxy的与CryptDB的交互

mysql-proxy提供了如下几个函数, 在客户端执行SQL的不同阶段, 会调用这几个函数, 这些函数实现在 wrapper.lua 中:

  • read_auth()
  • disconnect_client()
  • read_query(packet)
  • read_query_result(inj)

在上面的四个函数的实现中,调用了CryptDB的加密库中的几个函数,这些函数实现在 mysqlproxy/ConnectWrapper.cc 中,分别是:

  • connect
  • disconnect
  • rewrite
  • next

所以,所有的CryptDB操作,都是以上面的8个函数为基础的。对于CryptDB加密库而言,里面的connect以及disconnect 只在客户端建立连接和客户端离开的时候被调用,所有的加解密功能都是通过rewritenext这两个函数来完成,这两个函数就是CryptDB所有功能的入口。

回到mysql-proxy的lua脚本中的四个函数,可以分以下三个阶段来介绍。

客户端建立连接

在这个阶段,lua脚本中的函数read_auth被调用,其内部调用CryptDB的函数connect. 在这个阶段,需要为每个客户端建立一个WrapperState结构来保存相关的信息。不同的客户端通过ip+port来标识,多个客户端的信息则通过一个如下的map结构来进行保存:


std::map<std::string, WrapperState*> clients;

要使用加密库,还需要进行适当的初始化,并且多个client之间有共享状态。所以,如果当前连接进来的是第一个客户端,则需要对这个共享状态进行初始化,其对应的是一个变量:

SharedProxyState * shared_ps//多个client的共享状态

客户端离开

当客户端关闭的时候,lua脚本中的disconnect_client函数被调用。其内部调用CryptDB的disconnect函数。这个阶段会把map中保存的客户端的信息删除。

客户端的命令执行流程

客户端发送命令给mysql-proxy的时候,lua脚本中的read_query(packet)函数被调用,参数packet中包含了SQL命令。MySQL执行结果返回的时候,lua脚本中的read_query_result(inj)函数被调用,参数inj包含了返回结果。

  • 首先来看read_query函数。

当read_query 函数获取到客户端发送的明文SQL 命令的时候,会调用lua脚本中的read_query_real函数,其内部首先调用CryptDB库中的rewrite函数,完成SQL语句的改写。改写后的SQL语句保存在之前介绍过的 clients 结构中。然后调用lua脚本中的next _handler 函数,其内部调用CryptDB库中的next函数。在next函数中,首先执行函数获得一个参数result_type,分为三种情况,根据不同的结果选择不同的执行流程,包含了SQL命令执行的所有情况,分别如下:

//mysqlproxy/ConnectWrapper.cc

switch (result_type) {
    case AbstractQueryExecutor::ResultType::QUERY_COME_AGAIN: {
    //返回sql语句给lua脚本,执行结果再次进入该函数处理
    }
    case AbstractQueryExecutor::ResultType::QUERY_USE_RESULTS:{
    //返回sql语句给lua脚本,执行结果直接返回客户端
    }
    case AbstractQueryExecutor::ResultType::RESULTS:{
    //返回解密结果给lua脚本,并由mysql-proxy返回给客户端
    }
}

对于一般的SQL语句的执行,分为两种情况,第一种是直接进入QUERY_USE_RESULTS分支,返回SQL语句给lua脚本,SQL执行的结果直接返回给客户端。 第二种是进入第一个分支QUERY_COME_AGAIN,返回SQL语句给lua脚本转发到MySQL执行,返回的结果再次进入next函数,执行并且进入第三个分支,返回解密的结果给客户端。

另外,对于有些语句,并不需要调用rewrite函数进行加密,在lua脚本的阶段直接过滤了,这些情况就更加简单。

  • 然后来看read _query_results阶段。

当上面介绍的加密SQL语句发送给MySQL执行,并返回执行结果给mysql-proxy的时候,会调用lua脚本中的read _query_results(inj)函数。如果在read_query阶段进入了第二个分支,那么lua脚本会设置一个全局变量skip为true,read_query_results的处理就被跳过,直接返回结果给客户端。如果在read_query阶段进入了第一个分支,则会在这里再次调用next_handler函数,从而进入next函数,再次执行并进入switch分支的判断流程。

两个执行的例子

一些解密的细节以及类的介绍将在后续的文章中给出。在这里,给出两个SQL语句执行的例子,用于说明执行过程中lua脚本以及CryptDB库中的几个函数的调用过程,以及几个主要执行分支的含义。

  • show databases;

该命令的处理流程:
首先进入read_query,内部调用CryptDB的rewrite函数进行加密,然后调用lua中的next_handler,内部调用CryptDB的next函数,根据上面介绍的,进入switch的第二个分支,表示执行命令的结果不需要处理,直接返回给客户端。然后给lua脚本传递改写以后的命令。

再次回到lua脚本的next_handler函数,其处理了query results分支,将获得的命令转发给MySQL执行。执行完成以后的结果返回给mysql-proxy的时候,会调用read_query_result函数。根据上面介绍的,由于在read_query阶段进入了第二个分支,这里的处理会被跳过,也就是不做任何处理,结果直接返回给客户端。这样,客户端就得到了show databases的执行结果。

  • select * from student;

我们假设已经有了一张表,对其进行select操作,其对应的执行流程如下。
首先进入read_query,内部调用CryptDB的rewrite函数进行SQL语句的加密,返回以后调用lua中的next_handler函数,内部调用CryptDB的next函数,根据上面介绍的,进入第一个分支:QUERY_COME_AGAIN。返回加密以后的SQL命令给lua脚本。

在lua脚本中,next_handler处理了again分支,发送加密命令给MySQL,获得select返回的加密结果以后,lua脚本中的read_query_results被调用。由于在read_query阶段进入了第一个分支,这里会继续调用next_handler函数,并进入到next函数,执行获得result_type,然后这次进入到RESULTS分支。在lua脚本中,处理了results分支,将解密后的结果返回给客户端,这样就完成了整个流程。

总结

本文介绍了SQL加密执行过程中,mysql-proxy使用的lua脚本与CryptDB的加密库的交互过程,其中主要的几个函数是lua脚本中的read_query,read_query_results,以及CryptDB库中的rewrite和next。代码位于wrapper.lua以及mysqlproxy/ConnectWrapper.cc中。

参考文献

原始链接:yiwenshao.github.io/2018/02/26/CryptDB代码分析1-lua与加密库/

文章作者:Yiwen Shao

许可协议: Attribution-NonCommercial 4.0

转载请保留以上信息, 谢谢!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,706评论 4 366
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,002评论 1 301
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,462评论 0 250
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,375评论 0 216
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,763评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,849评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,033评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,768评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,490评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,734评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,204评论 1 264
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,566评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,227评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,137评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,934评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,926评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,774评论 2 274

推荐阅读更多精彩内容

  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,519评论 0 38
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,296评论 18 399
  • Nginx API for Lua Introduction ngx.arg ngx.var.VARIABLE C...
    吃瓜的东阅读 5,581评论 0 5
  • 好不容易临摹完心蓝丫头这幅花卉,说实话自己也没看明白这朵花到底怎么个样子,反正依葫芦画瓢临摹下来了,自己觉得不难看...
    LindaC阅读 295评论 0 0
  • 遥远的山 有自己的故事 曾经的恋人 化成石头变为永恒 远古的树 弥漫着神秘的颜色 是谁留下的 或许这就是传说 远方...
    长道赫书阅读 142评论 16 6