#前言 每一個公司都會遇到數據安全性的問題,數據在當下甚至將來,其安全性只會愈來愈重要。而在大數據的環境下,數據多以集羣存儲,量大而複雜是大數據的一個重要特徵,在這種狀況下,數據的安全性方案該如何設計才能保證數據安全,同時保證集羣負載小,對外透明度高呢?算法
目前的集羣情況是上了Kerberos
,我想這是集羣安全性的一個必要前提,即便你說集羣位於公司內網,可是沒上Kerberos談安全和權限就沒什麼卵用。其次集羣上了Sentry
,這是對權限管理的進一步增強,對Hive表可控制權限到列,對HDFS文件也可作具體權限控制。後端
一個公司大量的數據可能都是行爲數據,因此並無太多須要保密的處理,須要加密的每每是敏感數據,好比身份證信息,某些ID等。HDFS在文件層面提供了透明加密機制,配置好後可建立加密區,經過API又可把數據從加密區恢復出來,在DataNode端直接查看Block塊,數據是加密的,保證了安全性。可是它針對全部數據加密,雖然說對上層透明,安全好用,可是對集羣壓力大,不少不須要加密的數據作加密處理,是一種資源浪費。緩存
這裏想要提到的方案就是針對Hive表字段加密
,一個表具有幾十個字段,須要作保護的可能只有其中一兩個,經過提供一個UDF,在數據入Hive表時,在須要加密的字段上調用,UDF對上層透明,可實現數據保護。在數據須要解密的時候,一樣提供UDF用於解密,調用便可獲得明文。安全
#方案 上面的一個想法,造就了不少種不一樣方案,一個個嘗試,一個個排除,最後發現回到原點,只有一種方案合適。嘗試過的若干方案分兩大類,按處理類型分爲數據散列處理
和AES對稱加密
。併發
##數據散列處理 散列處理是指Hash一類的處理,算法有md5, sha1, sha-256以及更高位數的散列算法。它有個顯著特徵是雪崩效應,原文稍有改變,算出來的值就會徹底不一樣。Hash是一種摘要算法,同一種hash算法,針對不一樣的輸入,輸出的位數是固定的,因此hash存在碰撞的可能。在用於數據加密的時候,若是存在hash碰撞,就會致使數據丟失,一個明文會覆蓋另外一個明文。因此經過hash處理的話,就必須經過無碰撞或碰撞機率在可接受範圍內的驗證,同時敏感字段可能由於業務須要而在特定場景下須要還原,而hash不可逆,因此這種方案必須得作好明密文映射表。高併發
hash碰撞的機率可參考下圖: oop
對於字段的結構,若是咱們很清楚而且在可窮舉範圍內的話,咱們能夠選擇一個鹽,而後窮舉全部可能,從而能夠找到肯定無碰撞的鹽。對於沒法窮舉的,只能驗證一下碰撞機率是否在可接受範圍內。大數據
###把散列算法布成服務,對外提供明密文訪問的API 優點在於:加密
劣勢在於:.net
###在UDF裏作散列,控制鹽的權限,而後單獨起服務作映射表 一個字段對應一個鹽,控制好鹽的權限,好比把鹽存入Hive表裏,借用Sentry的權限控制實現表列的權限控制。在UDF裏獲取鹽,而後實現加密,可是解密須要從映射表來,因此得專門起服務作映射表。
優點在於:
劣勢在於:
以上是散列處理的兩種具體方案,因爲散列的不可逆,致使若是須要還原明文,它的代價就很是大,映射表的維護是極其麻煩的事情,並且備份和安全性都很差處理。但若是企業不要求還原,那這裏的第二種方案不失爲一個好的方案。
##AES對稱加密 AES纔是真正的加密算法,上述的散列只能是一種摘要算法,而非加密算法。
AES加密:一種對稱加密的算法,加密和解密使用同一種祕鑰。加密的過程是向量的移位運算過程,它會對輸入進行16字節的劃分,而後進行移位運算,解密則是其反向過程。
AES加密有不少不一樣的模式,不一樣模式的運算方式不同,有的模式還須要初始化向量。其中
CFB
和OFB
模式不會處理填充狀況(即輸入不滿16字節的,是否填充爲16字節)。因此AES的輸出長度與輸入長度是相關的,與祕鑰長度無關。規律:輸入是
16*n
字節,沒有填充的狀況下,輸出和輸入長度相同,有填充的狀況下,輸出爲16*(n+1)
。若是輸入不是 16字節的整數倍,是16*n
到16*(n+1)
的區間內,沒有填充的狀況下,輸出和輸入長度相同,有填充狀況下,輸出長度是16*(n+1)
在JDK裏默認有AES 128位的加解密API,若是須要更高位數的,就須要下載額外的jar包,但通常128位平常加密就夠使了。
在AES加密裏,咱們能夠把加密解密放在UDF裏,只需作好祕鑰Key的管理便可。
前期有個誤解,覺得Sentry能控制UDF的使用權限,最後驗證發現,Sentry其實只能控制UDF的建立權限,而不能控制使用權限。一個普通用戶想要有UDF的建立權限,則必須給他關聯上hive.aux.jars.path
裏配置的目錄下的jar包的ALL權限。
因此權限的控制只能放在Key的權限上,全部能取到Key的人,就具有了這個key所對應字段的加解密權限。前期覺得能對UDF和Key都作權限控制,這樣分兩級權限,把祕鑰在後端作的更透明,能夠增強權限的管理,有些人無需解密操做,就能夠把解密的UDF不對他開放。結果發現只是咱們本身樂了一下~
在AES加解密的祕鑰控制上,又有幾種不一樣的細分方案。針對祕鑰的存儲,分爲Hive表存儲
和KMS祕鑰管理服務存儲
。
###Hive表存儲祕鑰 這種方式比較簡單(事實證實簡單粗暴的每每是最好用的~),很好理解。經過建立多個列,不一樣列對應不一樣字段的祕鑰,利用Sentry把權限控制到列,即把權限控制到了字段key的級別。
###KMS祕鑰管理服務 它是Hadoop自己提供的一個祕鑰管理組件,用於HDFS文件加密的,咱們能夠利用它做爲咱們祕鑰管理的服務,它支持Kerberos認證和SSL,同時對權限可控制到具體key,權限管理上很是方便。
關於KMS祕鑰管理服務,這裏有單獨的一篇文章作介紹,KMS祕鑰管理服務
未完待續,下篇博客見 也說Hadoop敏感信息加密方案嘗試(下)
歡迎小主們轉載,但請註明出處:http://www.javashuo.com/article/p-cwsywivt-gw.html