揭祕!業界創新的代碼倉庫加密技術

簡介: 原理與演示。

image.png

 

01 / 什麼是代碼加密?

 

雲端加密代碼服務是雲效團隊的自研產品,是目前國內率先支持代碼加密的託管服務,也是目前世界範圍內率先基於原生Git實現加密方案的代碼託管服務。

 

通過在雲端對託管在雲效Codeup的代碼庫進行落盤加密,可以有效避免數據擁有者之外的人接觸到用戶的明文數據,避免數據在雲端發生泄露。同時,代碼加密過程對用戶完全透明,用戶可以使用任意官方Git端(包括但不限於Git、JGit、libgit2等)來訪問Codeup上的代碼倉庫。

02 / Linux社區重大安全性事件回顧

2011年8月底,用於維護和分發Linux操作系統的多臺服務器感染了惡意軟件,這些惡意軟件非常厲害,可以獲取root的訪問權限,修改其上的系統軟件以及登錄密碼。但社區的維護者稱,維護linux的源代碼,是未受到漏洞影響的。

 

這是爲什麼呢?因爲他們使用了Git進行代碼維護,對於linux內核代碼將近40000個文件來說,每個文件都做了hash來確保唯一性,因此很難在不引起注意情況下,更改舊的版本。

 

image.png

 

雖然Git可以解決開源社區關心的源碼篡改問題,卻解決不了企業擔心的數據泄露問題。而對於企業級代碼託管來說,今天所面臨的問題不但有數據安全、還有可靠性成本問題

 

當企業規模較小時,對可靠性要求也不高,一個自建的代碼託管服務似乎就能滿足需求。但隨着規模不斷擴大,代碼量不斷增加,可能需要更好的服務器配置,才能滿足多人協作的需求,甚至還需要投入專人維護來保證可靠性,這時就不得不思考成本的問題。

 

而云代碼託管服務,有着比自建代碼託管服務更高的可靠性及更低的成本,但相比自建代碼託管服務而言,由於其並不開放底層存儲的直接訪問,間接造成了用戶不可控的安全心理。

 

而代碼加密技術,正是通過將底層存儲的不可控變爲近完全可控,解決用戶代碼上雲的顧慮。

 

03 / 自建真的比上雲更安全麼?

 

在回答這個問題之前,讓我們一起來了解一些背景知識——Git的存儲結構。

 

image.png

 

當我們使用Git進行代碼提交時,最先接觸到的便是提交記錄及分支。分支或者標籤,可以統稱爲引用。它們存儲在以路徑名作爲引用名,以及對應版本hash作爲內容的單個文件中。由於分支名通常與業務無關,所以可以認爲,其中不包含敏感數據的。

 

除了提交記錄commit之外,我們的代碼文件被存儲到blob對象,文件名及目錄等信息,存儲到tree對象,帶有額外的信息的標籤被存儲到tag對象。

 

對象是Git中存儲數據的基本單元。通常情況下,對象存儲在以內容hash值命名的單個文件中,我們稱之爲鬆散對象。而通過執行gc(也就是垃圾回收)之後,這些對象就會被打包到一起,生成一個打包文件packfile。代碼內容及文件名,都存儲在blob及tree對象當中,所以可以認爲,對象中是包含用戶的代碼內容數據,也就是包含敏感數據的。

 

Git中的對象存儲,爲了降低磁盤佔用,會通過zlib進行一次數據的壓縮。換句話說,只需通過解壓縮就可以獲取到數據內容,所以可以認爲是明文存儲。也就是說,任意可以接觸到存儲的人,都可以查看存儲上的代碼數據。

明文存儲引發的信任問題

回答前面提出的問題,正是由於Git代碼非安全存儲的特點,自建的代碼託管服務,既要防範來自外部的一些攻擊風險,還要防範內鬼,因爲通常企業代碼數據泄露是從內部發生

 

image.png

 

而對於雲代碼託管服務而言,我們可以藉助阿里雲安全,有效避免來自外部的黑客攻擊風險,那麼,如何解決用戶對雲代碼託管服務的信任問題,讓代碼對運維人員不可見呢?

 

引入代碼加密技術,通過使用用戶的密鑰,加密雲端託管的代碼數據,既增加了靜態存儲數據的安全性,又可以阻斷代碼對運維人員的可見性,從而消除用戶上雲的顧慮。

04 / 代碼加密技術揭祕

我把它分化三個問題去解決:

1.密鑰管理

使用一個安全合規的方式託管密鑰,密鑰存儲安全,才能保證加密安全。這個可以藉助阿里雲的密鑰管理服務KMS。

 

2.密鑰使用

Git是一個計算密集型的服務,如果直接使用密鑰管理服務的加解密能力,那麼這個性能是難以接受的。

 

那這裏還有什麼方案呢?我們可以使用信封加密技術。顧名思義,我們可以使用數據密鑰,來對我們明文的代碼數據進行加密,使用數字信封技術,保證密鑰保存、傳輸、使用過程的安全性。由於我們只存儲密文的數據密鑰及密文的代碼數據,必須通過用戶授權,才能完成運行態的代碼數據解密。而處於靜態存儲的代碼數據,則無法被運維人員獲取。

 

3.基於原生Git的加密實現

在原生Git的基礎上,通過增加代碼加密補丁,以在實現加密的能力同時,最大程度地獲取到原生Git帶來的各種優勢。

原生Git是如圖所示的這樣一個自上而下的分層架構,和我們常見的應用架構非常類似。

 

image.png

 

最上層是展現層,包含紛繁複雜的命令行入口,直接暴露給應用服務進行調用。

 

中間是業務處理層,從數據內容角度,可以分爲引用操作及對象操作。通過增加一個加解密的模塊,在內存中進行數據加密,將密文數據寫入磁盤,從而保證靜態數據的安全性。

 

爲了獲取最高的性能,僅選擇與用戶代碼資產相關的對象數據進行加密存儲,而對於引用列表及對象索引等數據,仍維持明文存儲。利用硬件加速,代碼加密的額外性能損耗控制在10%左右,在用戶使用過程中幾乎無感。

本地Git代碼加密演示

事先準備好一個配置了代碼加密的的倉庫。這個倉庫是空的。

我們向裏面添加一個文件。

通過hexdump -C查看這個文件的二進制內容,我們可以發現,它是以首字節78 01起始,這是一個典型的經過zlib壓縮後的文件頭。

 

image.png

 

接下來,我們開啓加密的開關,通過git commit創建一個加密的提交記錄。再次查看保存的提交記錄二進制內容,發現這時創建的對象數據不再以78 01開始,而是以我們指定的加密標記位開始。

 

注意,受時間關係,這裏我們未進行同一個對象非加密與非加密狀態下的直接對比,而是以文件頭是否變化來判斷加密與否

 

在完成鬆散對象加密之後,我們可以通過git gc ,將鬆散對象轉換爲打包對象,再看一下打包對象會發生什麼樣的變化呢?由圖中我們可以發現,加密後的打包文件包頭版本中,不再是原有的00 00 00 02,而是增加了特定標識的82 00 00 02,並且包頭也由原有的12字節擴展爲24字節,增加了12字節的NONCE用於增加安全性。

 

image.png

 

那麼,當我們移除密鑰配置之後,是否可以繼續訪問這個倉庫呢?

當我們移除密鑰之後,由於缺少密鑰,當我們嘗試通過git show HEAD 查看當前版本時,會得到一個錯誤信息,提示未提供密鑰。

這個錯誤是基於我們在原生Git基礎上,定製化了代碼加密能力補丁,若是沒有這個補丁,會有什麼樣的表現呢?

針對加密的打包文件packfile,會提示當前版本較低,請升級Git版本;若針對鬆散對象,則提示文件頭不正確,因爲不是一個zlib的壓縮頭。

image.png

 

 歡迎大家使用雲效代碼管理Codeup,全方位保護企業代碼資產,幫助企業實現安全、穩定、高效的代碼託管和研發管理。

原文鏈接

本文爲阿里雲原創內容,未經允許不得轉載。

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