滴滴被罰,數據安全該怎麼做?——大數據安全入門寶典

2022年7月21日,大家都被一則新聞刷屏了。

經查實,滴滴全球股份有限公司違反《網絡安全法》《數據安全法》《個人信息保護法》的違法違規行爲事實清楚、證據確鑿、情節嚴重、性質惡劣。

7月21日,國家互聯網信息辦公室依據《網絡安全法》《數據安全法》《個人信息保護法》《行政處罰法》等法律法規,對滴滴全球股份有限公司處人民幣80.26億元罰款,對滴滴全球股份有限公司董事長兼CEO程維、總裁柳青各處人民幣100萬元罰款。

這已經不是數據安全的問題第一次出現在公衆面前,作爲數據從業者,我們也應該意識到數據安全的重要性。

而在大數據生態,基於Hadoop的技術架構雖然日漸成熟,但是由於組件衆多,實現統一的安全管控的難度巨大。爲了圖省事,相信還有大部分企業的Hadoop集羣依然處於“裸奔”的狀態,只要連上網絡,知道賬號密碼,就可以暢通無阻的訪問數據。這些其實都存在着巨大隱患。

所以,在大數據安全的治理上,我們需要做的工作還有很多。

本文將通過數據安全的意義,數據安全知識體系,大數據安全實踐,Kerberos 認證,Apache Ranger實踐,數據加密六個部分來介紹。

本文將介紹大數據安全的理論與實踐經驗,特別是實踐部分,如果這些工作都還沒有做的話,建議逐步開展,數據治理是一個長期的過程,不管是數據安全還是之前我們一直在學習的元數據管理與數據質量等等問題,都需要不斷的完善。

爲了更專注提高效率,目前數據治理相關學習交流羣按不同方向做了區分,歡迎大家掃碼入羣:

另外 數據治理工具箱 知識星球也已成立,這是一個數據治理落地實踐方向的知識星球。大數據流動發佈的數據治理相關文章與資料(包括付費內容)都將在知識星球進行長期同步。星球的目標是收集數據治理實踐工具的相關資料,並定期組織實戰學習小組,讓數據治理的相關資料可以長久的保存,同時也解決文章被頻繁抄襲的問題,歡迎大家加入。

未來,我們也會整理更多數據安全相關的資料與實踐經驗,任重道遠,我們共同努力~

正文共: 12094字

預計閱讀時間: 31分鐘

一、數據安全的意義

在談數據安全的意義之前,我們先來看一下滴滴本次到底有哪些違法行爲。

問:滴滴公司存在哪些違法違規行爲?

答:經查明,滴滴公司共存在16項違法事實,歸納起來主要是8個方面。一是違法收集用戶手機相冊中的截圖信息1196.39萬條;二是過度收集用戶剪切板信息、應用列表信息83.23億條;三是過度收集乘客人臉識別信息1.07億條、年齡段信息5350.92萬條、職業信息1633.56萬條、親情關係信息138.29萬條、“家”和“公司”打車地址信息1.53億條;四是過度收集乘客評價代駕服務時、App後臺運行時、手機連接桔視記錄儀設備時的精準位置(經緯度)信息1.67億條;五是過度收集司機學歷信息14.29萬條,以明文形式存儲司機身份證號信息5780.26萬條;六是在未明確告知乘客情況下分析乘客出行意圖信息539.76億條、常駐城市信息15.38億條、異地商務/異地旅遊信息3.04億條;七是在乘客使用順風車服務時頻繁索取無關的“電話權限”;八是未準確、清晰說明用戶設備信息等19項個人信息處理目的。

除了一些明顯有違法行爲的操作以外,這裏特別注意的一點就是 明文形式存儲司機身份證號信息5780.26萬條。很明顯,在敏感信息的存儲上,未進行加密處理。

​ 數據安全意義重大 伴隨着互聯網的迅猛發展和數字經濟的快速推進,全球數據呈現爆發增長、海量集聚的特點,對經濟發展、社會治理、 國家管理、人民生活都產生了重大影響。數據作爲前沿技術開發、隱私安全保護的重要內容,讓數據安全的重要性提到 了前所未有的高度。保障數據安全不僅涉及到公民個人隱私,還涉及到企業長遠發展和國家安全。 事實上,數字信息化發展一直伴隨着安全問題。

​ 近幾年來《數據安全法》《個人信息保護法》相繼出臺,也表明了數據安全的重要性越來越高。

對數據安全缺乏管控將會引起一系列的問題。

大數據遭受異常流量攻擊

大數據所存儲的數據非常巨大,往往採用分佈式的方式進行存儲,而正是由於這種存儲方式,存儲的路徑視圖相對清晰,而數據量過大,導致數據保護,相對簡單,黑客較爲輕易利用相關漏洞,實施不法操作,造成安全問題。

大數據信息泄露風險

大數據平臺的信息泄露風險在對大數據進行數據採集和信息挖掘的時候,要注重用戶隱私數據的安全問題,在不泄露用戶隱私數據的前提下進行數據挖掘。

大數據傳輸過程中的安全隱患

數據生命週期安全問題。伴隨着大數據傳輸技術和應用的快速發展,在大數據傳輸生命週期的各個階段、各個環節,越來越多的安全隱患逐漸暴露出來。

個人隱私安全問題。在現有隱私保護法規不健全、隱私保護技術不完善的條件下,互聯網上的個人隱私泄露失去管控。

二、數據安全知識體系

​ 《中華人民共和國數據安全法》中第三條,給出了數據安全的定義,**是指通過採取必要措施,確保數據處於有效保護和合法利用的狀態,以及具備保障持續安全狀態的能力。要保證數據處理的全過程安全,數據處理,包括數據的收集、存儲、使用、加工、傳輸、提供、公開等。

​ 在《DAMA數據管理知識體系指南》中也對數據安全管理給出了具體的定義:定義、規劃、開發、執行安全策略和和規程,以提供對數據和信息資產的適當驗證、授權、訪問、審計

數據安全如何開展呢?有以下一個步驟:

  • 1.識別敏感數據資產並分
    級分類
  • 2.在整個企業中查找敏感
    數據
  • 3.確定保護每項資產的方
  • 4.識別信息與業務流程如
    何交互

這裏就要注意,在數據安全中有幾個關鍵的詞語,就是訪問審計分級分類監控加密

下面我用一些通俗的語言解釋一下~

訪問指的是,對於誰可以訪問數據應該是有一定機制的,而且安全性應該非常的高,不應該是簡單的賬號密碼就能解決的。

審計指的是,對於數據的使用,應該是有記錄的,不能是用完了也不知道是誰用了。

分級分類這個不搞數據安全的可能想不到,但是數據量大了以後,不可能所有數據都用一個規範去管理的。分級分類也更專業更高效。

監控報警機制就更爲重要,當出現了問題的時候,應該第一時間就發現問題所在。

加密是一個大的概念,對於敏感信息的處理,加密是一種手段,但不僅僅是加密那麼簡單。如何加密、解密,並保持高的處理性能,這是我們需要解決的問題。

三、大數據安全實踐

​ 每一個數據框架的出現都會考慮數據安全的問題,Hadoop的安全問題不是一個新的概念,而是一個老生常談的問題。

​ 結合數據安全的理論知識,Hadoop安全可以總結爲五點核心問題:

安全認證

任何用戶都可以僞裝成爲其他合法用戶,訪問其在HDFS上的數據,獲取MapReduce產生的結果,從而存在惡意攻擊者假冒身份,篡改HDFS上他人的數據,提交惡意作業破壞系統、修改節點服務器的狀態等隱患。

權限控制

用戶只要得知數據塊的 Block ID 後,可以不經過 NameNode 的身份認證和服務授權,直接訪問相應 DataNode,讀取 DataNode 節點上的數據或者將文件寫入 DataNode 節點。

關鍵行爲審計

默認hadoop缺乏審計機制。

靜態加密

默認情況下Hadoop 在對集羣HDFS 系統上的文件沒有存儲保護,所有數據均是明文存儲在HDFS中,超級管理員可以不經過用戶允許直接查看和修改用戶在雲端保存的文件,這就很容易造成數據泄露。

動態加密

默認情況下Hadoop集羣各節點之間,客戶端與服務器之間數據明文傳輸,使得用戶隱私數據、系統敏感信息極易在傳輸的過程被竊取。

對此Hadoop其實做了一系列的治理工作。

Doug Cutting 和 Mike Cafarella 最初爲 Nutch 項目開發 Hadoop 時並沒有考慮安全因素,這是衆所周知的事實。因爲 Hadoop 的最初用例都是圍繞着如何管理大量的公共 web 數據,無需考慮保密性。按照 Hadoop 最初的設想,它假定集羣總是處於可信的環境中,由可信用戶使用的相互協作的可信計算機組成。

最初的 Hadoop 中並沒有安全模型,它不對用戶或服務進行驗證,也沒有數據隱私。因爲 Hadoop 被設計成在分佈式的設備集羣上執行代碼,任何人都能提交代碼並得到執行。儘管在較早的版本中實現了審計和授權控制(HDFS 文件許可),然而這種訪問控制很容易避開,因爲任何用戶只需要做一個命令行切換就可以模擬成其他任何用戶。這種模擬行爲非常普遍,大多數用戶都會這麼幹,所以這一已有的安全控制其實沒起到什麼作用。

Hadoop 社區意識到他們需要更加健壯的安全控制,決定重點解決認證問題,選擇 Kerberos 作爲 Hadoop 的認證機制。

不久之後Cloudera公司發佈的一個Hadoop開源組件,Apache Sentry。Sentry解決了細粒度訪問控制,以及基於角色的管理。這是對權限管理的進一步加強,對Hive表可控制權限到列,對HDFS文件也可做具體權限控制。Apache Sentry目前已經成爲退休項目了。

Hortonworks公司也發佈了Apache Ranger。其提供了細粒度級Hive列級別的權限控制,並支持與Kerberos 集成。

除此以外,其他的組件也含有了一部分數據安全的功能。比如:

Apache Falcon:Apache Falcon是一個開源的hadoop數據生命週期管理框架, 它提供了數據源 (Feed) 的管理服務,如生命週期管理,備份,存檔到雲等,通過Web UI可以很容易地配置這些預定義的策略, 能夠大大簡化hadoop集羣的數據流管理。

Apache Atlas:是一個可伸縮和可擴展的元數據管理工具與大數據治理服務,它爲Hadoop集羣提供了包括數據分類、集中策略引擎、數據血緣、安全和生命週期管理在內的元數據治理核心能力。

但是敏感信息處理的問題還是沒有得到解決。

Apache Hadoop 2.9.1版本正式提出了HDFS 透明加密的概念,詳見http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/TransparentEncryption.html

概念如下:HDFS實現透明的,端到端(transparent, end-to-end)的加密。配置以後,從特殊HDFS目錄讀取和寫入的數據將透明地加密和解密,而不需要更改用戶應用程序代碼。這種加密也是端到端的,這意味着數據只能由客戶端來進行加密和解密。HDFS從不存儲或訪問未加密數據或未加密數據加密密鑰,這滿足了加密的兩個典型要求:靜態加密(at-rest encryption)(指永久介質(如磁盤)上的數據)和傳輸中的加密(in-transit encryption)(如數據通過網絡傳輸時)。

透明加密安全好用,但是對集羣壓力大,很多不需要加密的數據做加密處理,其實是一種資源浪費。

所以在部分公司也採用了方案就是針對Hive表的字段加密的方式。一個表具備幾十個字段,需要做保護的可能只有其中一兩個,通過提供一個UDF,在數據入Hive表時,在需要加密的字段上調用,UDF對上層透明,可實現數據保護。在數據需要解密的時候,同樣提供UDF用於解密,調用即可得到明文。

而且加密解密對於性能的影響巨大,特別是Flink爲主的實時計算框架穩定以後,數據的實時性提高。單純的HDFS全量加密顯然不能滿足需求了,所以對於加密方式的研究也不能停止。

篇幅有限,下面我們對Kerberos,Apache Ranger和加密方式進行一個基本的介紹。

更詳細的教程,請關注 大數據流動 ,後續將會持續更新~

四、Kerberos 認證

Kerberos 是一種身份認證協議,被廣泛運用在大數據生態中,甚至可以說是大數據身份認證的事實標準。

​ Kerberos協議本質上是一種計算機網絡授權協議,用於在非安全的網絡環境下對個人通信進行加密認證。Kerberos協議認證過程的實現不依賴於主機操作系統的認證,不需要基於主機地址的信任,不要求網絡上所有主機的物理安全,並且是以假定網絡上傳送的數據包可以被任意的讀取、修改和插入數據爲前提設計的。

簡而言之,如果你要去請求服務,你要獲取2個票據,1個叫許可票據,1個叫服務票據,去服務器請求服務之前,你必須擁有服務票據,但是你要去請求服務票據的時候,你又必須攜帶許可票據,拿到了這2個票據,你才能夠有資格去真實服務器上去請求服務。

​ Kerberos 的核心就是加密 Ticket 。Kerberos 主要由三個部分組成:Key Distribution Center (即KDC)、Client 和 Service。

聽起來有些繁瑣,通俗解釋一下。

首先要有一個Ticket,才能夠申請訪問權限,隨後不同的Ticket還具有不同的權限。

我們實戰一下,就更好理解了。

Kerberos部署

Kerberos需要部署服務端和客戶端。

主節點安裝服務:

yum install krb5-server -y

其他子節點安裝krb5-devel、krb5-workstation :

yum install krb5-devel krb5-workstation -y

服務端包含三個配置文件:

有三個配置文件可以做對應的修改:

/etc/krb5.conf

/var/kerberos/krb5kdc/kdc.conf

/var/kerberos/krb5kdc/kadm5.acl

創建Kerberos數據庫

kdb5_util create -r localhost -s

-r指定配置的realm領域名

啓動服務

chkconfig --level 35 krb5kdc on
chkconfig --level 35 kadmin on
systemctl start krb5kdc
systemctl start kadmin

創建Kerberos管理員

kadmin.local -q "addprinc admin/admin"

測試Kerberos

kadmin.local -q "list_principals"
kadmin.local -q "addprinc dy"
kinit dy
klist
kinit -R
kdestroy
kadmin.local -q "delprinc dy"

如果需要與CDH集成,要將Kerberos的憑據信息導入進來。

用戶身份認證獨立於HDFS之外,也就說HDFS並不負責用戶身份合法性檢查,但HDFS會通過相關接口來獲取相關的用戶身份,然後用於後續的權限管理。用戶是否合法,完全取決於集羣使用認證體系。目前社區支持兩種身份認證,即簡單認證(Simple)和Kerberos。模式由hadoop.security.authentication屬性指定,默認simple。

simple 認證

基於客戶端所在的Linux/Unix系統的登錄用戶名來進行認證。只要用戶能正常登錄就認證成功。客戶端與NameNode交互時,會將用戶的登錄賬號(通過類似whoami的命令來獲取)作爲合法用戶名傳遞至Namenode。 這意味着使用不同的賬號登錄到同一個客戶端,會產生不同的用戶名,故在多租戶條件這種認證會導致權限混淆;同時惡意用戶也可以僞造其他人的用戶名非法獲得相應的權限,對數據安全造成極大的隱患。線上生產環境一般不會使用。

啓用 kerberos認證

啓用 HDFS安全性 修改下面參數

hadoop.security.authentication ---> kerberos
hadoop.security.authorization ---> true

啓用HBASE安全修改下面參數

hbase.security.authentication ---> kerberos
hbase.security.authorization ---> true

這些都啓動以後,再次訪問hdfs就沒有那麼簡單了,必須要有keytab的認證文件纔可以了。

下面是一個簡單的例子:

 System.setProperty("java.security.krb5.conf", "D:\\HDFS-test\\krb5.conf");
        conf=new Configuration();
        conf.addResource(new Path("D:\\HDFS-test\\hdfs-site.xml"));
        conf.set("hadoop.security.authentication", "kerberos"); //配置認證方式
        conf.set("fs.default.name", "hdfs://localhost:8020");//namenode的地址和端口
        UserGroupInformation.setConfiguration(conf);
        try {
            UserGroupInformation.loginUserFromKeytab("hdfs/gz237-112", "D:\\HDFS-test\\hdfs.keytab");
        } catch (IOException e) {
            e.printStackTrace();
        }

五、Apache Ranger實踐

Ranger是一個集中式安全管理框架,提供集中管理的安全策略和監控用戶訪問,而且它可以對hadoop生態系統上的組件如hive、hbase等進行細粒度的數據訪問控制,並解決授權和審計問題。通過操作Ranger控制檯,管理員可以輕鬆的通過配置策略來控制用戶訪問HDFS文件夾、HDFS文件、數據庫、表、字段權限。

優點:

提供了細粒度級(hive列級別)
基於訪問策略的權限模型
權限控制插件式,統一方便的策略管理
支持審計日誌,可以記錄各種操作的審計日誌,提供統一的查詢接口和界面
豐富的組件支持(HDFS,HBASE,HIVE,YARN,KAFKA,STORM)
支持和kerberos的集成
提供了Rest接口供二次開發
選擇Ranger的原因
多組件支持(HDFS,HBASE,HIVE,YARN,KAFKA,STORM),基本覆蓋我們現有技術棧的組件
支持審計日誌,可以很好的查找到哪個用戶在哪臺機器上提交的任務明細,方便問題排查反饋
擁有自己的用戶體系,可以去除kerberos用戶體系,方便和其他系統集成,同時提供各類接口可以調用

Ranger 使用了一種基於屬性的方法定義和強制實施安全策略。當與 Apache Hadoop 的數據治理解決方案和元數據倉儲組件Apache Atlas一起使用時,它可以定義一種基於標籤的安全服務,通過使用標籤對文件和數據資產進行分類,並控制用戶和用戶組對一系列標籤的訪問。

Ranger 的總體架構如下圖所示,主要由以下三個組件構成:

RangerAdmin

以RESTFUL形式提供策略的增刪改查接口,同時內置一個Web管理頁面。

Service Plugin

嵌入到各系統執行流程中,定期從RangerAdmin拉取策略,根據策略執行訪問決策樹,並且記錄訪問審計

Ranger-SDK

對接開放平臺,實現對用戶、組、策略的管理

Ranger 安裝部署

官網下載源碼包

wget http://mirrors.tuna.tsinghua.edu.cn/apache/ranger/2.0.0/apache-ranger-2.0.0.tar.gz

編譯Ranger

# cd /home/apache-ranger-2.0.0 
# mvn clean compile package assembly:assembly install -DskipTests -Drat.skip=true

解壓ranger-admin軟件包

tar -zxvf ranger-2.0.0-admin.tar.gz 

修改install.properties文件

# cd /home/ranger-2.0.0-SNAPSHOT-admin

# vim install.properties

初始化ranger-admin

# cd /home/ranger-2.0.0-SNAPSHOT-admin
# vi setup.sh
# ./setup.sh 

啓動ranger-admin

# ranger-admin start 

啓動地址爲http://locahost:6080,登錄界面用戶名和密碼爲:admin/admin

隨後需要進行一些插件的安裝:

隨後就可以進行一些授權的操作了。

六、數據加密

6.1 Hadoop加密

HDFS支持原生靜態加密,屬於應用層加密。該方法中,數據被髮送和到達存儲位置之前,在應用層被加密。這種方法運行在操作系統層之上。

HDFS中,需要加密的目錄被分解成若干加密區(encryption zone);

加密區中的每個文件都被使用唯一的數據加密密鑰(data encryprion key,DEK)進行加密;

明文DEK不是永久的,而是用一個名爲加密區密鑰(encryption zone key,EZK)的區域級加密密鑰,將DEK加密成加密DEK(encrypted DEK,EDEK);

EDEK作爲指定文件NameNode元數據中的擴展屬性永久存在。

除了hdfs和client客戶端之外,還有一個重要的出場角色是KMS。

KMS(key management server)密鑰管理服務器,是一個在hadoop-common工程裏,獨立於hdfs的組件,它相當於一個管理密鑰的服務器有自己的dao層和後端數據庫,用來作爲發放透明加密密鑰的第三方。

KMS的密鑰由特定權限的用戶管理,權限也是獨立於hdfs的,特權用戶登陸後通過命令來創建密鑰。

hadoop key create [keyName]

初始化加密區

這一步需要hdfs的特殊用戶登陸操作,特殊用戶首先創建要加密的加密區

hadoop fs -mkdir /data-encrypt

把這一目錄的權限賦給普通用戶hive

hadoop fs -chown hive:hive /data-encrypt

然後使用生成的密鑰創建加密區

hdfs crypto -createZone -keyName [keyName] -path /data-encrypt
用戶使用hdfs時,存到加密區的數據都會以數據塊形式存儲到hdfs節點的meta文件中,打開後是一堆亂碼,而客戶端用指令hadoop fs -cat還是get指令得到的都是明文,這就是端對端加密。我們可以通過以下方式得到加密文件的數據塊。

hdfs fsck /data-encrypt -files -blocks -locations

6.2 字段加密與加密算法

前文也提到過,如果要想提高性能,並且支持更多靈活的組件,還是要使用字段級的加密方式。

我們先來了解一下常見的加密知識。

什麼是數據加密 ?

數據加密 的基本過程,就是對原來爲 明文 的文件或數據按 某種算法 進行處理,使其成爲 不可讀 的一段代碼,通常稱爲 “密文”。通過這樣的途徑,來達到 保護數據 不被 非法人竊取、閱讀的目的。

解密

加密 的 逆過程 爲 解密,即將該 編碼信息 轉化爲其 原來數據 的過程。

對稱加密 和 非對稱加密

加密算法分 對稱加密 和 非對稱加密,其中對稱加密算法的加密與解密 密鑰相同,非對稱加密算法的加密密鑰與解密 密鑰不同,此外,還有一類 不需要密鑰 的 散列算法。

常見的 對稱加密 算法主要有 DES3DESAES 等。

常見的 非對稱算法 主要有 RSADSA 等。

常見的 散列算法 主要有 SHA-1MD5 等。

直接學習原理比較晦澀,下面我們選幾個常見的實戰一下。

AES加密算法

高級加密標準(AES,Advanced Encryption Standard)爲最常見的對稱加密算法。

  • 明文P

沒有經過加密的數據。

  • 密鑰K

用來加密明文的密碼,在對稱加密算法中,加密與解密的密鑰是相同的。

  • AES加密函數

加密函數爲E,則 C = E(K, P),其中P爲明文,K爲密鑰,C爲密文。也就是說,把明文P和密鑰K作爲加密函數的參數輸入,則加密函數E會輸出密文C。

  • 密文C

經加密函數處理後的數據

  • AES解密函數

設AES解密函數爲D,則 P = D(K, C),其中C爲密文,K爲密鑰,P爲明文。也就是說,把密文C和密鑰K作爲解密函數的參數輸入,則解密函數會輸出明文P。

對稱加密算法加密和解密用到的密鑰是相同的,這種加密方式加密速度非常快,適合經常發送數據的場合。缺點是密鑰的傳輸比較麻煩。

實際中,一般是通過RSA加密AES的密鑰,傳輸到接收方,接收方解密得到AES密鑰,然後發送方和接收方用AES密鑰來通信。

Java版AES實現:

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.SecureRandom;
import java.util.Base64;

public class AESUtil {
    private static final String ALGORITHM = "AES";

    //密鑰的存放位置
    private String keyUrl = "D:/aes.key";

    /**
     * 生成密鑰
     * @return
     * @throws Exception
     */
    private SecretKey geneKey() throws Exception {
        //獲取一個密鑰生成器實例
        KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        random.setSeed("123456".getBytes());//設置加密用的種子,密鑰,這個可不操作,固定了的話每次出來的密鑰時一樣的
        keyGenerator.init(random);
        SecretKey secretKey = keyGenerator.generateKey();
        //把上面的密鑰存起來
        Path keyPath = Paths.get(keyUrl);
        Files.write(keyPath, secretKey.getEncoded());
        return secretKey;
    }


    /**
     * 讀取存儲的密鑰
     * @param keyPath
     * @return
     * @throws Exception
     */
    private SecretKey readKey(Path keyPath) throws Exception {
        //讀取存起來的密鑰
        byte[] keyBytes = Files.readAllBytes(keyPath);
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, ALGORITHM);
        return keySpec;
    }

    /**
     * 加密
     */
    public String encrypt(String encryptStr) throws Exception {
        //1、指定算法、獲取Cipher對象
        Cipher cipher = Cipher.getInstance(ALGORITHM);//算法是AES
        //2、生成/讀取用於加解密的密鑰
        SecretKey secretKey = this.geneKey();
        //3、用指定的密鑰初始化Cipher對象,指定是加密模式,還是解密模式
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        //4、更新需要加密的內容
        cipher.update(encryptStr.getBytes());
        //5、進行最終的加解密操作
        byte[] result = cipher.doFinal();//加密後的字節數組
        //也可以把4、5步組合到一起,但是如果保留了4步,同時又是如下這樣使用的話,加密的內容將是之前update傳遞的內容和doFinal傳遞的內容的和。
//      byte[] result = cipher.doFinal(content.getBytes());
        String base64Result = Base64.getEncoder().encodeToString(result);//對加密後的字節數組進行Base64編碼
        return base64Result;
    }

    /**
     * 解密
     */
    public String decrpyt(String desrpytStr) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        Path keyPath = Paths.get(keyUrl);
        SecretKey secretKey = this.readKey(keyPath);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] encodedBytes = Base64.getDecoder().decode(desrpytStr.getBytes());
        byte[] result = cipher.doFinal(encodedBytes);//對加密後的字節數組進行解密
        return new String(result);
    }
    
    
    public static void main(String[] args) throws Exception {
        AESUtil aesUtil = new AESUtil();
        String enctyptStr = aesUtil.encrypt("bigdata");
        System.err.println(enctyptStr);
        String decrpytStr = aesUtil.decrpyt(enctyptStr);
        System.err.println(decrpytStr);
    }
}

RSA加密算法

RSA加密算法是目前應用最廣泛的公鑰加密算法。RSA加密算法是1978年提出的。經過多年的分析和研究,在衆多的公開密鑰加密算法中,RSA加密算法最受推崇,它也被推薦爲公開密鑰數據加密標準。

RSA 加密算法 基於一個十分簡單的數論事實:將兩個大 素數 相乘十分容易,但想要對其乘積進行 因式分解 卻極其困難,因此可以將 乘積 公開作爲 加密密鑰

RSA加密算法是非對稱加密算法,非對稱加密算法的加密和解密用的密鑰是不同的,這種加密方式是用數學上的難解問題構造的,通常加密解密的速度比較慢,適合偶爾發送數據的場合。優點是密鑰傳輸方便。常見的非對稱加密算法爲RSA、ECC和EIGamal。

Java版RSA實現:

import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException,
            InvalidKeyException, SignatureException, UnsupportedEncodingException {
        // 生成祕鑰
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        keyGen.initialize(2048, random);
        KeyPair pair = keyGen.generateKeyPair();

        PrivateKey priv = pair.getPrivate();
        PublicKey pub = pair.getPublic();

        String privStr = Base64.getEncoder().encodeToString(priv.getEncoded());
        String pubStr = Base64.getEncoder().encodeToString(pub.getEncoded());

        // 字符串轉祕鑰對象
        PrivateKey privKey = getPrivateKey(privStr);
        PublicKey pubKey = getPublicKey(pubStr);

        String plaintext = "私鑰簽名測試";
        // 私鑰簽名
        Signature rsaPrivSig = Signature.getInstance("SHA1withRSA");
        rsaPrivSig.initSign(privKey);
        rsaPrivSig.update(plaintext.getBytes("UTF-8"));
        byte[] privSign = rsaPrivSig.sign();
        String privSignStr = Base64.getEncoder().encodeToString(privSign);

        // 公鑰驗籤
        Signature rsaPubSig = Signature.getInstance("SHA1withRSA");
        rsaPubSig.initVerify(pubKey);
        rsaPubSig.update(plaintext.getBytes("UTF-8"));
        boolean verifies = rsaPubSig.verify(Base64.getDecoder().decode(privSignStr));
        System.out.println("signature verifies: " + verifies);
    }

MD5加密算法

MD5是一種數據散列處理算法。

數據散列處理是指Hash一類的處理,算法有md5, sha1, sha-256以及更高位數的散列算法。它有個顯著特徵是雪崩效應,原文稍有改變,算出來的值就會完全不同。Hash是一種摘要算法,同一種hash算法,針對不同的輸入,輸出的位數是固定的,所以hash存在碰撞的可能。在用於數據加密的時候,如果存在hash碰撞,就會導致數據丟失,一個明文會覆蓋另一個明文。

MD5的Java實現例子:

public class MD5 {
public final static String encode(String str) {
return encodeMd5(str);

}

private final static String encodeMd5(String s) {
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',

'A', 'B', 'C', 'D', 'E', 'F' };

try {
byte[] btInput = s.getBytes();

MessageDigest mdInst = MessageDigest.getInstance("MD5");

mdInst.update(btInput);

byte[] md = mdInst.digest();

int j = md.length;

char str[] = new char[j * 2];

int k = 0;

for (int i = 0; i < j; i++) {
byte byte0 = md[i];

str[k++] = hexDigits[byte0 >>> 4 & 0xf];

str[k++] = hexDigits[byte0 & 0xf];

}

return new String(str);

} catch (Exception e) {
e.printStackTrace();

return null;

}

}

public static void main(String agrs[]) {
String md2 = encode("123456");

System.out.println(md2);

}

}

說了半天還沒有一個結論,由於散列的不可逆,導致如果需要還原明文,它的代價就非常大,映射表的維護是極其麻煩的事情,而且備份和安全性都不好處理。

而非對稱加密的性能很差,非對稱加密適合對密鑰的保護

而敏感信息的加密還是使用對稱加密算法比較好,在AES加密裏,我們可以把加密解密放在UDF裏,只需做好祕鑰Key的管理即可。

未完待續~

最後提醒,文檔版權爲公衆號 大數據流動 所有,請勿商用。相關技術問題以及安裝包可以聯繫筆者獨孤風加入相關技術交流羣討論獲取。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章