龍蜥白皮書精選:基於 SM4 演算法的檔案加密(fscrypt)實踐
文/張天佳
通常我們會以檔案作為資料載體,使用磁碟,USB 快閃記憶體,SD 卡等儲存介質進行資料儲存,即便資料已經離線儲存,仍然不能保證該儲存介質不會丟失,如果丟失那麼對於我們來說有可能是災難性的事件。因此對這些離線儲存的重要資料檔案進行加密是非常有必要的,本節將介紹如何使用國密演算法加密檔案系統中的檔案。
01 fscrypt 簡介
核心中的 fscrypt 是一個庫,檔案系統可以使用它以支援檔案和目錄的透明加密。
與 dm-crypt 不同,fscrypt 在檔案系統級別而不是塊裝置級別執行。這允許它使用不同的金鑰加密不同的檔案,並在同一檔案系統上擁有未加密的檔案。這對於多使用者系統非常有用,在該系統中,每個使用者的靜態資料都需要與其他使用者進行加密隔離。除了檔名,fscrypt 不加密檔案系統的後設資料。
與作為棧式檔案系統的 eCryptfs 不同,fscrypt 是直接整合到支援的檔案系統中,目前支援 fscrypt 的檔案系統是 ext4、F2FS 和 UBIFS。fscrypt 允許讀取和寫入加密檔案,而無需在頁面快取中同時快取解密和加密頁面,從而將使用的記憶體幾乎減半並使其與未加密檔案保持一致。同樣,需要一半的 dentry 和 inode。eCryptfs 還將加密檔名限制為 143 位元組,從而導致應用程式相容性問題;fscrypt 允許完整的 255 個位元組 (NAME_MAX)長度的檔名。最後,與 eCryptfs 不同,fscrypt API 可以由非特權使用者使用,而無需依賴其它任何元件。
fscrypt 不支援就地加密檔案。相反,它支援將空目錄標記為已加密。然後,在使用者空間提供金鑰後,在該目錄樹中建立的所有常規檔案、目錄和符號連結都將被透明地加密。
02 支援的加密模式和用法
fscrypt 允許為檔案內容指定一種加密模式,為檔名指定一種加密模式。不同的目錄樹允許使用不同的加密方式。目前支援以下幾種加密方式對:
-
AES-256-XTS 演算法用於加密內容,AES-256-CTS-CBC 演算法用於加密檔名
-
AES-128-CBC 演算法用於加密內容,AES-128-CTS-CBC 演算法用於加密檔名
-
Adiantum 演算法同時用於加密檔案內容和檔名
-
AES-256-XTS 演算法用於加密內容,AES-256-HCTR2 演算法用於加密檔名(僅限 v2 策略)
-
SM4-XTS 演算法用於加密內容,SM4-CTS-CBC 演算法用於加密檔名(僅限 v2 策略)
AES-128-CBC 僅為具有不支援 XTS 模式的加速器的低功耗嵌入式裝置使用。要使用 AES-128-CBC,必須啟用 CONFIG_CRYPTO_ESSIV 和 CONFIG_CRYPTO_SHA256(或其他 SHA-256 實現)以便使用 ESSIV。
Adiantum 是一種基於流密碼的模式,即使在沒有專用加密指令的 CPU 上也很快。與 XTS 不同,它也是真正的寬塊模式。要使用 Adiantum,必須啟用 CONFIG_CRYPTO_ADIANTUM。此外,應啟用 ChaCha 和 NHPoly1305 的快速實現,例如 ARM 架構上的 CONFIG_CRYPTO_CHACHA20_NEON 和 CONFIG_CRYPTO_NHPOLY1305_NEON。
AES-256-HCTR2 是另一種真正的寬塊加密模式,旨在用於具有專用加密指令的 CPU。AES-256-HCTR2 具有明文中的位翻轉會更改整個密文的屬性。由於初始化向量在目錄中重複使用,因此此屬性使其成為檔名加密的理想選擇。要使用 AES-256-HCTR2,必須啟用 CONFIG_CRYPTO_HCTR2。此外,應啟用 XCTR 和 POLYVAL 的快速實現,例如 用於 ARM64 的 CRYPTO_POLYVAL_ARM64_CE 和 CRYPTO_AES_ARM64_CE_BLK。
最後是 SM4 演算法,目前僅在 fscrypt v2 策略中啟用。
03 使用 SM4 演算法加密檔案
? 準備工作
fscrypt 依賴核心配置 CONFIG_FS_ENCRYPTION=y,這裡作業系統選擇使用 ANCK 5.10 核心的 Anolis OS,其次,需要支援 fscrypt 特性的檔案系統,這裡以 ext4 為例,當然,F2FS 或者 UBIFS 也可以。
使用者空間是透過 fscrypt API 跟核心完成互動的,對於使用者來說,一般是透過 fscryptctl 或者 fscrypt 工具來下達加密策略。
本節內容以 fscryptctl() 工具為例來演示,目前這是一個第三方工具,需要手工安裝,按如下常規流程安裝:
git clone .git cd fscryptctl make make install
其次,選擇一塊未用到的磁碟格式化為支援 fscrypt 的檔案系統 ext4,並掛載。
mkfs.ext4 -O encrypt /dev/vda3 mount /dev/vda3 /mnt
? 透明加密檔案
fscrypt 所用的加解金鑰是關聯在超級塊上的,執行時是跟掛載點相關聯的,新增刪除金鑰都是針對掛載點的操作,以下對金鑰操作的命令都會帶上掛載點。
按如下命令所示設定加密策略:
# 生成金鑰檔案,實際環境中應用使用更復雜的金鑰 > echo '1234567812345678' > /tmp/keyfile # 新增該金鑰到檔案系統,返回金鑰ID,之後對金鑰的操作都使用這個ID來索引 > fscryptctl add_key /mnt < /tmp/keyfile 23086a13ed81fd75ca5fe9b8f2ff25c7 # 檢視金鑰狀態(不是必需) > fscryptctl key_status 23086a13ed81fd75ca5fe9b8f2ff25c7 /mnt Present (user_count=1, added_by_self) # 建立加密目錄 endir,並設定加密策略 # 使用之前新增的金鑰和 SM4 演算法來加密該目錄中的檔案和子目錄 > mkdir /mnt/endir > fscryptctl set_policy --contents=SM4-XTS \ --filenames=SM4-CTS 23086a13ed81fd75ca5fe9b8f2ff25c7 /mnt/endir # 檢視策略是否生效(不是必需) > fscryptctl get_policy /mnt/endir Encryption policy for /mnt/endir: Policy version: 2 Master key identifier: 23086a13ed81fd75ca5fe9b8f2ff25c7 Contents encryption mode: SM4-XTS Filenames encryption mode: SM4-CTS Flags: PAD_32
此時,endir 已經是支援透明加解密的一個目錄,可以像正常目錄一樣建立刪除檔案,在該目錄下進行一些常規的檔案操作,可以看到與普通目錄沒有區別:
> mkdir /mnt/endir/foo > echo 'hello' > /mnt/endir/foo/hello > cp -v /usr/include/curl/* endir > tree /mnt/endir /mnt/endir ├── curl.h ├── easy.h ├── foo │ └── hello └── websockets.h
? 鎖定加密目錄
之所以能像普通目錄一樣操作,是因為金鑰已經被新增到了檔案系統中。接下來刪除金鑰後,就能看到目錄被鎖定,裡面的所有路徑和內容都是加密狀態:
# 移除金鑰 > fscryptctl remove_key 23086a13ed81fd75ca5fe9b8f2ff25c7 /mnt > fscryptctl key_status 23086a13ed81fd75ca5fe9b8f2ff25c7 /mnt Absent # 處於加密狀態的目錄樹 > tree /mnt/endir /mnt/endir ├── 1H2e0BbS4MGZKAKEu6NVXniaYMWIrWDwbyzX6EVEWEN8tfWcWNgDyw ├── LvYw6Jl0a1jImKKOFPjtpG3hEDxjjuM6YIYqcMeXaWdzKUdaX0YCNQ ├── QBBz8_qGE4MJY6YVzfqVUkr6YeCSqtoQmbvG04BsR0lAr2oLwO0b2g │ └── wOYdFlMRACjeBa-eSo3LuO4sE55q1YuFv-S_lVU-n498jdMjAt06JA └── zoiobWxVG2DLjg8uMXfsVP11159zqQUjozJ8gmt1zyjayJlZ4awOhA # 目錄被鎖定,無法進行常規檔案操作,即便拔盤,也不能得到明文內容 > cat /mnt/endir/1H2e0BbS4MGZKAKEu6NVXniaYMWIrWDwbyzX6EVEWEN8tfWcWNgDyw cat: /mnt/endir/1H2e0BbS4MGZKAKEu6NVXniaYMWIrWDwbyzX6EVEWEN8tfWcWNgDyw: Required key not available > mkdir /mnt/endir/hello mkdir: cannot create directory ‘/mnt/endir/hello’: Required key not available
? 再次解鎖加密目錄
要解鎖目錄也很簡單,重新新增金鑰即可,檔案系統會搜尋到正確的金鑰並解鎖相應目錄:
> fscryptctl add_key /mnt < /tmp/keyfile 23086a13ed81fd75ca5fe9b8f2ff25c7 # 新增金鑰後檔案內容可正常訪問 > cat /mnt/endir/foo/hello hello
04 後記
fscryptctl 是一個相對原生的工具,更接近核心,可以看到,該工具命令比較複雜,使用中需要記住很長一串金鑰 ID,使用者體驗並不好。
實際環境中,一般會使用 fscrypt 工具來完成加密策略操作,該工具由 Google 開發,用 Go 語言寫成,透過在使用者層面維護了一些後設資料來簡化使用者操作,命令更易於理解,也更接近使用者。
商密軟體棧 SIG 主頁:
附:商用密碼技術最 佳實踐白皮書
—— 完 ——
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70004278/viewspace-2943208/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 龍蜥白皮書精選:跨雲-邊-端的只讀檔案系統 EROFS
- 商密SIG月度動態:檔案加密支援SM4演算法、Anolis 8.8將預設整合 | 龍蜥 SIG加密演算法
- 龍蜥白皮書精選:面向 DPU 場景的軟硬協同協議棧協議
- 龍蜥白皮書精選:龍蜥全面支援 Intel 第四代可擴充套件處理器 SPR 平臺Intel套件
- 龍蜥白皮書精選:敏捷開發場景下的排程器熱升級 SDK敏捷
- 基於 Coolbpf 的應用可觀測實踐 | 龍蜥技術
- 首次!龍蜥社群生態使用者實踐精選集釋出在即
- Java實現常用加密演算法-SM4Java加密演算法
- 龍蜥社群聯合浪潮資訊釋出《eBPF技術實踐白皮書》(附下載連結)eBPF
- Inspur KOS 龍蜥衍生版面向智慧新媒體轉型的探索與實踐 | 龍蜥案例
- 萬里資料庫加入龍蜥社群,打造基於“龍蜥+GreatSQL”的開源技術底座資料庫SQL
- 系統效能監控工具ssar例項精選 | 龍蜥SIG
- 《可信計算技術最 佳實踐白皮書》釋出,龍蜥助力可信計算技術應用推廣(可下載)
- 技術門檻高?來看 Intel 機密計算技術在龍蜥社群的實踐 | 龍蜥技術Intel
- 載入速度提升 15%,關於 Python 啟動加速探索與實踐的解析 | 龍蜥技術Python
- 藏書館App基於Rainbond實現雲原生DevOps的實踐APPAIdev
- 一文帶你學會國產加密演算法SM4的vue實現方案加密演算法Vue
- 一文帶你學會國產加密演算法SM4的java實現方案加密演算法Java
- 龍蜥 Node.js/WebAssembly SIG 重磅釋出 Node.js/Noslate 效能最佳化白皮書Node.jsWeb
- 基於lerna+yarn workspaces的monorepo專案實踐YarnMono
- 簡單、透明、安全、高度整合!龍蜥可信 SBOM 能力探索與實踐
- 螞蟻安全科技 Nydus 與 Dragonfly 映象加速實踐 | 龍蜥技術Go
- 基於github的CICD實踐Github
- 讀書筆記(四):深度學習基於Keras的Python實踐筆記深度學習KerasPython
- 精準測試白皮書 2020 版
- 精準測試白皮書2020版
- 檔案IO操作的最佳實踐
- KeenTune的演算法之心——KeenOpt 調優演算法框架 | 龍蜥技術演算法框架
- c#使用SHA256演算法實現對檔案的加密和解密C#演算法加密解密
- C語言實現檔案加密C語言加密
- 基於量子隨機遊走的影像加密演算法隨機加密演算法
- 基於DevOps的容器安全實踐dev
- 浙江移動容器雲基於 Dragonfly 的統一檔案分發平臺生產實踐Go
- 鬥魚大佬分享!基於圖的團伙挖掘演算法實踐演算法
- Yocto實踐(1): 基於Dunfell 構建Yocto專案
- iOS精選必看書籍iOS
- 龍蜥開源Plugsched:首次實現 Linux kernel 排程器熱升級 | 龍蜥技術Linux
- 基於vue.ant.design的單檔案方式遞迴生成選單Vue遞迴