版權(quán)聲明:本文為博主原創(chuàng)文章,歡迎轉(zhuǎn)載;轉(zhuǎn)載請注明來自 瓜哥
http://www.itdecent.cn/p/1bf893765b2c
博主寫的另外幾篇相關(guān)文章:
想要理解CryptDB, 你可能需要閱讀如下資料:
CryptDB. Popa, R. A., et al. (2011). CryptDB: protecting confidentiality with encrypted query processing. [文章鏈接](http://web.cs.ucdavis.edu/~franklin/ecs228/2013/popa_etal_sosp_2011.pdf)
Guidelines for Using the CryptDB System Securely [鏈接](https://eprint.iacr.org/2015/979)
其他可能有用的資源:
CryptDB?有軟件的下載和使用介紹。
GitHub - CryptDB/cryptdb: A database system that can process SQL queries over encrypted data.?這個比較方便,建議看這個!
Raluca Ada Popa's Homepage?建議~
主要結(jié)構(gòu):
Database proxy和一個unmodifiedDBMS
User-defined functions (UDFs) [用來執(zhí)行密碼操作]
安全保障:
面對thread1:
將所有的SQL查詢用proxy攔截。
利用proxy加解密從DBMS傳過來的數(shù)據(jù),也會轉(zhuǎn)換一些操作(比如說計算方面的+會利用*代替)
面對thread2:
原理看得不是很懂,只知道是說對于不同的數(shù)據(jù)是會采用不同的數(shù)據(jù)進行加密的(比如說不同用戶的加密秘鑰是不同的)。
但是在這個情況下是能夠保護到?jīng)]有在數(shù)據(jù)庫被攻擊期間登錄的用戶的。而且僅僅是thread1下采取的措施是不足以保證thread2下的安全的,因為敵人可以得到密鑰
Thread1下的密碼學(xué)實現(xiàn):
幾個密碼算法的簡要概括:
RND:
最高級別的密碼學(xué)保護,所有的計算都是不被允許的,甚至相同的兩個明文映射到的都是不同的密文!(這里看圖一感覺就不是很懂了!為什么會支持COUNT和UPDATE這樣的操作??大神請告訴我)
DET
只會暴露那些相同的映射關(guān)系,所以可以執(zhí)行=的斷言操作。
理論上可以實現(xiàn):
join,GroupBy, count, distinct, in, not in, =, !=
OPE
可以在密文上實現(xiàn)排序!因為加密之后的密文仍然會暴露他們的大小關(guān)系。
理論上可以實現(xiàn):
Orderby, min, max, sort
HOM(同態(tài)加密)
可以實現(xiàn)在加密的密文上的計算,但是需要轉(zhuǎn)換!原理:HOMk(x)*HOMk(y)=HOMk(x+y)通過吧加密值相乘可以求出和的加密值。同樣計算average時返回count值和sum值即可!
理論上可以實現(xiàn):
Sum,multiply, average
JOIN
Join的設(shè)置是有必要的,因為DET的實現(xiàn)使用了不同的key以防止跨列相關(guān)聯(lián)(作者的話=。=難以理解)。
SEARCH
支持LIKE操作,利用了特殊的規(guī)則把內(nèi)容分成塊狀,去重(重復(fù)的字塊)之后打亂順序再使用Song
et al的算法加密,非常安全,幾乎可以達到和RND一樣的加密程度(因為DBMS只能通過UDF和傳入的密文檢查是否match到,其他的信息對于DBMS來說都是一抹黑)。
請結(jié)合下圖了解幾種加密算法之間差別,甚至同一個算法在不同的使用場景之下都會有不同的加密效果!
圖一
實際的運用場景:
概念:可調(diào)節(jié)的基于查詢的加密
解釋:為了在提供數(shù)據(jù)庫服務(wù)的同時保證最高的安全保障,cryptDB會調(diào)節(jié)加密的方式。
下面的洋蔥圖展示了在最原始的情況下,數(shù)據(jù)被加密的情況。每向外一層都代表了更高程度的加密。同樣的基于性能的考慮,為不同的數(shù)據(jù)類型準(zhǔn)備幾種不同的洋蔥絲有必要的。例如:對于string類型add操作是沒有意義的,對于integer來說search操作也是毫無效果的。
圖二
加密的秘鑰是不同的,僅僅在同一個onion層和同一列下key是統(tǒng)一的。這樣防止DBMS獲取到更多別的關(guān)系下的信息。
解開加密層:
利用DECRYPT_***
UDF(***是某種加密算法)這個UDF是嵌入到查詢語句之中的。例如:
UPDATE Table1 SET
C2-Ord= DECRYPT RND(K, C2-Ord, C2-IV)
解密操作只會發(fā)生在對于查詢對數(shù)據(jù)加密要求貶低的時候,在要求不變的時候,解密操作不會發(fā)生。
兩種join
Equi-join和range
join。
為了實現(xiàn)equi-join不同的列之間必須用同樣的key進行加密,否則數(shù)據(jù)庫實際上沒有辦法進行對比的操作。另外不能join到一起的列不能夠使用同樣的key(意思是因為某些原因,即使是可以join的,但是應(yīng)用層不希望他們可以執(zhí)行join操作)
在上面的討論之后,如果事先知道了要join的列名equi-join是很容易實現(xiàn)的。但是問題是如果proxy代理并不知道呢(因為在DBMS內(nèi)無論是表名還是列名都是隱藏的)?事情會變得比較復(fù)雜。
JOIN-ADJ
為了解決列對(column pair)不是先驗的情況下join操作的執(zhí)行問題,CryptDB給出了JOIN-ADJ這種‘新的’密碼學(xué)原型(其實不是很新就是了)。
JOIN-ADJ是個啥?
論文里談到JOIN-ADJ是一種【對輸入確定性的函數(shù)】(就是相同的明文對應(yīng)的一定是相同的JOIN-ADJ值),同時也是【可調(diào)整的利用秘鑰加密之后的hash值】(意思是這個hash值由對應(yīng)的加密算法生成,而且?guī)в锌烧{(diào)整的附加屬性的)。
JOIN-ADJ怎么使用?
首先JOIN-ADJ是不可置反的。
因此利用了JOIN-ADJ的JOIN加密方案由如下所示:
JOIN(v) = JOIN-ADJ(v)||DET(v)…….(這里的||符號起到連接字符串的作用)
在這個結(jié)構(gòu)之下,CryptDB通過比較JOIN-ADJ(v)來實現(xiàn)比較屬性名是否相同,通過解密DET(v)來獲取被加密的屬性值。
當(dāng)每次proxy悉知了有心得JOIN操作到來,它會向DBMS傳遞一個key使得DBMS可以調(diào)整兩個列之間的JOIN-ADJ值,使得他們的值趨于一致(就是變成一樣的)(當(dāng)然必須明文要是相同的才行)。一旦他們經(jīng)過了調(diào)整,之后對于這兩個列的JOIN操作就無需再次調(diào)整他們的JOIN-ADJ值了,因為他們會將這個值保留,直到需要作出改變?yōu)橹埂?/p>
顯然,這里提到的JOIN操作是具有可傳遞性的,AB、AC可以實現(xiàn)JOIN,那么BC同樣可以。這樣ABC形成了一個所謂的“可傳遞組”的概念(看起來其實就是屬性閉包嘛)。
注意他這里為什么要用“可傳遞組”這樣一個奇葩的名稱,實際上作者的對于可以實現(xiàn)JOIN操作的列對的管理是通過這樣的標(biāo)記來實現(xiàn)的:(表名+列名),并不是普通意義上的屬性閉包。根據(jù)作者的說法,這樣的標(biāo)記是出于【避免波動】(不是很懂)這樣的考慮,而且是為了讓所有在“可傳遞組”中的列能共享同樣的join-base。
CryptDB通過選擇字母表順序上的第一個標(biāo)簽作為join-base,因此如果每次有新表加入,而且這個表的標(biāo)簽會成為新的join-base的話,n個列的情況下,總共需要n(n-1)/2次join轉(zhuǎn)換(即對JOIN-ADJ值的調(diào)整)
JOIN-ADJ的生成
這里沒有難度,請自己看生成方式。
威脅2下的CryptDB:
第四章在一個論壇網(wǎng)站phpBB的模型上討論了這個問題——如何在數(shù)據(jù)庫陷入險境的時候,減輕收到的數(shù)據(jù)損失?
CryptDB作出了以下兩種保證來處理威脅2。
1.私人之間傳遞的信息是對他人隔離的。
2.某個論壇中發(fā)表的言論信息只有屬于該論壇的人才能看見。
這樣的保證有兩個挑戰(zhàn):
1.在SQL查詢的層次就需要獲取對于共享信息的權(quán)限控制策略。(因此要在建表的時候聲明principles)【4.1】
2.減少敵方能夠獲取的信息量(key chaining)【4.2】
策略的注解:
軟件開發(fā)人員通過對CryptDB中數(shù)據(jù)庫模式結(jié)構(gòu)的定義,來指定在SQL查詢這個層次上的策略。
如何進行注解?
開發(fā)人員會指定每一個數(shù)據(jù)實例其對應(yīng)的principle是什么。Principle是一個實體,例如一個用戶或者一個小組,利用他們可以很好的對權(quán)限進行定義。
CryptDB使用的是自己定義的principal而不是現(xiàn)成的DBMS的principles。因為現(xiàn)成的principle提供的定義細(xì)粒度不夠,不足以滿足開發(fā)的需求。其二CryptDB在principle之間需要實現(xiàn)顯式的特權(quán)授予(SPECK_FOR),這也是現(xiàn)有的DBMS principle不能夠提供的!
注:特權(quán)的意思其實就是能夠?qū)?shù)據(jù)進行解密操作。
注解需要以下3步:
請對照下面的定義來理解!
Step1:
定義principle types:利用PRINCTYPE關(guān)鍵字定義。每一個principle都是某個principle type的實例(就類似C++里面變量和變量類型的概念)
一共有兩種principle:external和internal(注意是除了external就是internal了下面不再重復(fù)這個概念)。
External:這種principle代表了那些端用戶(end user),這些端用戶通過顯式的使用密碼得到自己的權(quán)利。
Internal:這種principle的特權(quán)是可以被external的principle獲取的,但是只能通過顯式的聲明來實現(xiàn)授予。
Step2:
顯式的定義每一列是否包含有敏感的信息,同時也定義哪些principle擁有獲取這些敏感信息的權(quán)利。使用ENC_FOR來實現(xiàn)這樣的操作。如下圖中的表privmsgs中,只有principle 5可以解密msgtext x37a21f。
Step3:
可以利用SPEAK_FOR定義授權(quán)的規(guī)則。語法:(a x) SPEAKS_FOR (b y)
直譯過來這個聲明的意思就是x類a principle聲明了自己擁有y類b
principle的特權(quán)。其實對著表來看的話就是a這個屬性獲取了b這個屬性的特權(quán)。
注意:b這個屬性只能待在聲明所在的這張表里面,但是a就不一樣了,a可以待在別的表里面。
Key Chaining
其實沒有說前面說的“屬性”用來代替principle其實是不準(zhǔn)確的說法。到了Key Chaining這里是絕對不可以用的。
每一個principle實例其實都關(guān)聯(lián)了一個隨機選擇的key。假如某個principle A給另外一個principle B授權(quán)了,就是B speaks for A,那么A的key將會用B的key加密然后存儲到數(shù)據(jù)庫中的access_keys表格中。
敏感區(qū)域的數(shù)據(jù)是用和前面onion同樣的方式加密的,區(qū)別在于這里是每一個實例都會被單獨加密,而不是整一列使用同樣的秘鑰加密。
每個principle實例的key是由對稱秘鑰和公鑰私鑰對組成的。公鑰加密開銷比較大,因此普通情況下principle都是用對稱密鑰加密的。可是也有特殊情況,一旦涉及到有的principle沒有登錄,這時候別的principle都是沒有辦法獲知沒有登錄的principle的對稱密鑰的,所以利用公鑰加密的方法,把明文用公鑰加密傳給對方,等到對方上線的時候使用私鑰解密即可。
CryptDB為每一個external principle派發(fā)一個隨機key,這個key被存放在external_keys表格里面
每當(dāng)?shù)胤较胍ㄟ^更改SPEAKS_FOR來窺探隱私信息的時候,CryptDB的機制告訴我們,需要對access_keys表格進行相應(yīng)的更改,想要更改這個表格必須獲得被授權(quán)principle的key(前面講過的),這就意味著只有這個principle登錄的時候,敵方才能獲取相應(yīng)的key從而對這個principle的私密信息進行窺探。