做網(wǎng)站用什么配資電腦千鋒教育介紹
一、問題解析
在一個應用系統(tǒng)運行過程中,需要記錄、傳輸很多數(shù)據(jù),這些數(shù)據(jù)有的是非常敏感的,比如用戶姓名、手機號碼、密碼、甚至信用卡號等等。這些數(shù)據(jù)如果直接存儲在數(shù)據(jù)庫,記錄在日志中,或者在公網(wǎng)上傳輸?shù)脑?#xff0c;一旦發(fā)生數(shù)據(jù)泄露,不但可能會產生重大的經(jīng)濟損失,還可能會使公司陷入重大的公關與法律危機。公司上下辛苦十幾年,一夜回到解放前。
所以,敏感信息必須進行加密處理,也就是把敏感數(shù)據(jù)以密文的形式存儲、傳輸。這樣即使被黑客攻擊,發(fā)生數(shù)據(jù)泄露,被竊取的數(shù)據(jù)也是密文,獲取數(shù)據(jù)的人無法得到真實的明文內容,敏感數(shù)據(jù)依然被保護著。而當應用程序需要訪問這些密文的時候,只需要進行數(shù)據(jù)解密,即可還原得到原始明文數(shù)據(jù)。加解密處理既保證了數(shù)據(jù)的安全,又保證了數(shù)據(jù)的正常訪問。
但是,這一切的前提是加密和解密過程的安全。加密、解密過程由加密算法、加密密鑰、解密算法、解密密鑰組成。下圖是一個對稱加密、解密過程。對稱加密密鑰和解密密鑰是同一個密鑰,調用加密算法可將明文加密為密文,調用解密算法可將密文還原為明文。
所以,如果竊取數(shù)據(jù)的人知道了解密算法和密鑰,即使數(shù)據(jù)是加密的,也可以輕松對密文進行還原,得到原始的明文數(shù)據(jù)。而很多時候,解密算法和密鑰都以源代碼的方式保存在代碼倉庫里,黑客如果竊取了源代碼,或者內部人泄露了源代碼,那么所有的秘密就都不是秘密了。
此外,在某些情況下,我們的系統(tǒng)需要和外部系統(tǒng)進行對稱加密數(shù)據(jù)傳輸,比如和銀行加密傳輸信用卡卡號,這時候涉及到密鑰交換,即我方人員和銀行人員對接,直接傳遞密鑰。如果因密鑰泄露導致重大經(jīng)濟損失,那么持有密鑰的人員將無法自證清白,這又會導致沒有人愿意保管密鑰。
因此,我們設計了一個加解密服務系統(tǒng),系統(tǒng)名稱為“Venus”,統(tǒng)一管理所有的加解密算法和密鑰。應用程序只需要依賴加解密服務SDK,調用接口進行加解密即可,而真正的算法和密鑰在系統(tǒng)服務端進行管理,保證算法和密鑰的安全。
15.1 需求分析
一般說來,日常開發(fā)中的加解密程序存在如下問題:
- 密鑰(包括非對稱加解密證書)保存在源文件或者配置文件中,存儲分散而不安全。
- 密鑰沒有分片交換機制,不能滿足高安全級密鑰管理和交換的要求。
- 密鑰缺乏版本管理,不能靈活升級,一旦修改密鑰,此前加密的數(shù)據(jù)就可能無法解密。
- 加密解密算法程序不統(tǒng)一,同樣算法不同實現(xiàn),內部系統(tǒng)之間密文不能正確解析。
- 部分加解密算法程序使用了弱加解密算法和弱密鑰,存在安全隱患。
為此,我們需要設計開發(fā)一個專門的加解密服務及密鑰管理系統(tǒng),以解決以上問題。
Venus是一個加解密服務系統(tǒng),核心功能是加解密服務,輔助功能是密鑰與算法管理。此外,Venus還需要滿足以下非功能需求:
- 安全性需求- 必須保證密鑰的安全性,保證沒有人能夠有機會看到完整的密鑰。因此一個密鑰至少要拆分成兩片,分別存儲在兩個異構的、物理隔離的存儲服務器中 。在需要進行密鑰交換的場景中,將密鑰至少拆分成兩個片段,每個管理密鑰的人只能看到一個密鑰片段,需要雙方所有人分別交接才能完成一次密鑰交換。
- 可靠性需求- 加解密服務必須可靠,即保證高可用。無論在加解密服務系統(tǒng)服務器宕機、還是網(wǎng)絡中斷等各種情況下,數(shù)據(jù)正常加解密都需要得到保障。
- 性能需求- 加解密計算的時間延遲主要花費在加解密算法上,也就是說,加載加解密算法程序、獲取加解密密鑰的時間必須短到可以忽略不計。
根據(jù)以上加解密服務系統(tǒng)功能和非功能需求,系統(tǒng)用例圖設計如下:
系統(tǒng)主要參與者(Actor)包括:
系統(tǒng)主要用例過程和功能包括:
- 開發(fā)工程師使用密鑰管理功能為自己開發(fā)的應用申請加解密算法和密鑰;
- 安全工程師使用密鑰管理功能審核算法和密鑰的強度是否滿足數(shù)據(jù)安全要求;
- (經(jīng)過授權的)密鑰管理者使用密鑰管理功能可以查看密鑰(的一個分片);
- 應用程序調用加解密功能完成數(shù)據(jù)的加密、解密;
- 加密解密功能和密鑰管理功能調用密鑰服務功能完成密鑰的存儲和讀取;
- 密鑰服務功能訪問一個安全、可靠的密鑰存儲系統(tǒng)讀寫密鑰。
總地說來,Venus應滿足如下需求:
- 集中、分片密鑰存儲與管理,多存儲備份,保證密鑰安全易管理。
- 密鑰申請者、密鑰管理者、密鑰訪問者,多角色多權限管理,保證密鑰管理與傳遞的安全。
- 通過密鑰管理控制臺完成密鑰申請、密鑰管理、密鑰訪問控制等一系列密鑰管理操作,實現(xiàn)便捷的密鑰管理。
- 統(tǒng)一加解密服務API,簡單接口,統(tǒng)一算法,為內部系統(tǒng)提供一致的加解密算法實現(xiàn)。
15.2 概要設計
針對上述加解密服務及密鑰安全管理的需求,設計加解密服務系統(tǒng)Venus整體結構如下:
應用程序調用Venus提供的加解密SDK服務接口,對信息進行加解密,該SDK接口提供了常用的加密解密算法并可根據(jù)需求任意擴展。SDK加解密服務接口調用Venus密鑰服務器的密鑰服務,以取得加解密密鑰,并緩存在本地。而密鑰服務器中的密鑰則來自多個密鑰存儲服務器,一個密鑰分片后存儲在多個存儲服務器中,每個服務器都由不同的人負責管理。密鑰申請者、密鑰管理者、安全審核人員通過密鑰管理控制臺管理更新密鑰,每個人各司其事,沒有人能查看完整的密鑰信息。
15.2.1 部署模型
Venus部署模型如圖:
Venus系統(tǒng)的核心服務器是Key Server服務器,提供密鑰管理服務。密鑰分片存儲在文件服務器File Store和數(shù)據(jù)庫DB中。
使用Venus加解密服務的應用程序(Application)部署在應用程序服務器(App Server)中,依賴Venus提供的SDK API進行數(shù)據(jù)加解密。而Venus SDK 則是訪問密鑰服務器(Key Server)來獲取加解密算法代碼和密鑰。
安全起見,密鑰將被分片存儲在文件服務器(Key File Store)和數(shù)據(jù)庫服務器(Key DB)中。所以Key Server服務器中部署了密鑰管理組件(Key Manager),用于訪問數(shù)據(jù)庫中的應用程序密鑰元信息(Key Meta Data),以此獲取密鑰分片存儲信息。Key Server服務器根據(jù)這些信息訪問File Store和DB,獲取密鑰分片,并把分片拼接為完整密鑰,最終返回給SDK。
此外,密鑰管理控制臺(Key Console)提供一個web頁面,供開發(fā)工程師、安全工程師、密鑰管理者進行密鑰申請、更新、審核、查看等操作。
15.2.2 加解密調用時序圖
加解密調用過程如下時序圖所示。
- 應用程序App調用Venus SDK對數(shù)據(jù)進行加密(解密)。
- SDK檢查在本地是否有緩存加解密需要的密鑰和加解密算法代碼,如果有緩存,就直接使用該算法和密鑰進行加解密。
- 如果本地沒有緩存密鑰和算法,請求遠程服務器返回密鑰和算法。
- 部署在Venus服務器的Key Manager收到請求后,訪問數(shù)據(jù)庫,檢查該應用配置的密鑰和算法Meta信息。
- 數(shù)據(jù)庫返回的Mata信息中包括了密鑰的分片信息和存儲位置,Key Manager訪問文件服務器和數(shù)據(jù)庫,獲取密鑰分片,并將多個分片合并成一個完整密鑰,返回給客戶端SDK。
- SDK收到密鑰后,緩存在本地進程內存中,并完成對App加解密調用的處理。
通過該設計,我們可以看到,Venus對密鑰進行分片存儲,不同存儲服務器由不同運維人員管理。就算需要進行密鑰交換,那么參與交換的人員,每個人也只能獲得一個密鑰分片,無法得到完整的密鑰,這樣就保證了密鑰的安全性。
密鑰緩存在SDK所在的進程(也就是應用程序App所在的進程)中,只有第一次調用時會訪問遠程的Venus服務器,其他調用只訪問本進程緩存。因此加解密的性能只受加解密的數(shù)據(jù)大小和算法的影響,不受Venus服務的性能影響,滿足了性能要求。
同時,由于密鑰在緩存中,如果Venus服務器臨時宕機,或者網(wǎng)絡通信中斷,也不會影響到應用程序的正常使用,保證了Venus的可靠性。但是如果Venus服務器長時間宕機,那么應用重新啟動,本地緩存被清空,就需要重新請求密鑰,這時候應用就不可用了。那么Venus如何在這種情況下仍然保證高可用呢?
解決方案就是對Venus服務器、數(shù)據(jù)庫和文件服務器做高可用備份。Venus服務器部署2-3臺服務器,構建一個小型集群,SDK通過軟負載均衡訪問Venus服務器集群,若發(fā)現(xiàn)某臺Venus服務器宕機,就進行失效轉移。同樣,數(shù)據(jù)庫和文件服務器也需要做主從備份。
15.3 詳細設計
Venus詳細設計主要關注SDK核心類設計。其他的例如數(shù)據(jù)庫結構設計、服務器密鑰管理Console設計等,這里不做展開。
15.3.1 密鑰領域模型
為了便于SDK緩存、管理密鑰信息以及SDK與Venus服務端傳輸密鑰信息,我們設計了一個密鑰領域模型,如下圖:
- 一個應用程序使用的所有密鑰信息都記錄在KeyBox對象中,KeyBox對象中有一個keySuitMap成員變量,這個map的key是密鑰名稱,value是一個KeySuit對象。
- KeySuit類中有一個keyChainMap成員變量,這個map類的key是版本號,value是一個KeyChain對象。Venus因為安全性需求,需要支持多版本的密鑰。也就是說,對同一類數(shù)據(jù)的加密密鑰過一段時間就會進行版本升級,這樣即使密鑰泄露,也只會影響一段時間的數(shù)據(jù),不會導致所有的數(shù)據(jù)都被解密。
- KeySuit類的另一個成員變量currentVersion記錄當前最新的密鑰版本號,也就是當前用來進行數(shù)據(jù)加密的密鑰版本號。而解密的時候,則需要從密文數(shù)據(jù)中提取出加密密鑰版本號(或者由應用程序自己記錄密鑰版本號,在解密的時候提供給Venus SDK API),根據(jù)這個版本號獲取對應的解密密鑰。
- 具體每個版本的密鑰信息記錄在KeyChain中,包含了密鑰名稱name、密鑰版本號version、加入本地緩存的時間cache_time、該版本密鑰創(chuàng)建的時間versionTime、對應的加解密算法algorithm,當然,還有最重要的密鑰分片列表keyChipList,里面按序記錄著這個密鑰的分片信息。
- KeyChip記錄每個密鑰分片,包括分片編號no,以及分片密鑰內容chip。
15.3.2 核心服務類設計
應用程序通過調用加解密API VenusService完成數(shù)據(jù)加解密。如下圖:
- Venus SDK的核心類是VenusService,應用程序調用該對象的encrypt方法進行加密,decrypt方法進行解密。應用程序需要構造VenusData對象,將加解密數(shù)據(jù)傳給VenusService,VenusService加解密完成后創(chuàng)建一個新的VenusData對象,將加解密的結果寫入該對象并返回。VenusData成員變量在后面詳細講解。
- VenusService通過VenusConnector類連接Venus服務器獲取密鑰KeyBox和算法Algorithm,并調用Algorithm的對應方法完成加解密。
以加密為例,具體處理過程時序圖如下:
首先,應用程序App創(chuàng)建VenusData對象,并將待加密數(shù)據(jù)寫入該對象。接著,App調用VenusService的encrypt方法進行加密,VenusService檢查加密需要的密鑰和算法是否已經(jīng)有緩存,如果沒有,就調用VenusConnector請求服務器,返回密鑰和算法。VenusConnector將根據(jù)返回的算法字節(jié)碼來構造加密算法的實例對象,同時根據(jù)返回的密鑰構造相關密鑰對象,并寫入KeyBox,完成更新。
下一步,VenusService會根據(jù)更新后的KeyBox中的密鑰和算法進行加密,并將加密結果寫入VenusData。最后,應用程序App從返回的VenusData中獲取加密后的數(shù)據(jù)即可。
15.3.3 加解密數(shù)據(jù)接口VenusData設計
VenusData用于表示Venus加解密操作輸入和輸出的數(shù)據(jù),也就是說,加解密的時候構造VenusData對象調用Service對應的方法,加解密完成后返回值還是一個VenusData對象。
VenusData包含的屬性如下圖:
VenusData用作輸入時:
- 屬性bytes和text只要設置一個,即要么處理的是二進制bytes數(shù)據(jù),要么是Striing數(shù)據(jù),如果兩個都設置了,Venus會拋出異常。
- 屬性version可以不設置(即null),表示Venus操作使用的密鑰版本是當前版本。
- 屬性outputWithText表示輸出的VenusData是否處理為text類型,缺省值是true。
- 屬性dataWithVersion表示加密后的VenusData的bytes和text 中是否包含使用密鑰的版本信息,這樣在解密的時候可以不指定版本,缺省值是false。
如果dataWithVersion設置為true,即表示加密后密文內包含版本號,這種情況下,VenusService需要在密文頭部增加3個字節(jié)的版本號信息,其中頭兩個字節(jié)為固定的magic code:0x5E、0x23,第三個字節(jié)為版本號(也就是說,密鑰版本號只占用一個字節(jié),最多支持256個版本)。
VenusData用作輸出時,Venus會設置屬性keyName(和輸入時的值一樣)、version、 bytes、 outputWithText、dataWithVersion(和輸入時的值一樣),并根據(jù)輸入的 outputWithText決定是否設置text屬性。
15.3.4 測試用例代碼demo
publicstaticvoidtestVenusService()throws Exception {// 準備數(shù)據(jù)VenusDatadata1=newVenusData();data1.setKeyName("aeskey1");data1.setText("PlainText");// 加密操作VenusDataencrypt= VenusService.encrypt(data1);System.out.printf("Key Name: %s, Secret Text: %s, Version: %d.\n", encrypt.getKeyName(),encrypt.getText(), encrypt.getVersion());// 準備數(shù)據(jù)VenusDatadata2=newVenusData();data2.setKeyName("aeskey1");data2.setBytes(encrypt.getBytes());data2.setVersion(encrypt.getVersion());// 解密操作VenusDatadecrypt= VenusService.decrypt(data2);System.out.printf("Key Name: %s, Plain Text: %s, Version: %d.\n", decrypt.getKeyName(),decrypt.getText(), decrypt.getVersion());}
二、粉絲福利
最近很多同學問我有沒有java學習資料,我根據(jù)我從小白到架構師多年的學習經(jīng)驗整理出來了一份80W字面試解析文檔、簡歷模板、學習路線圖、java必看學習書籍?、 需要的小伙伴 可以關注我
公眾號:“?灰灰聊架構?”, 回復暗號:“?159?”即可獲取