介紹如何在 Linux 中使用薩莫爾祕密共享方法(Shamir’s secret sharing scheme),將一把金鑰分成多個部分,分別讓多人保管,加強金鑰保存的安全性。
薩莫爾祕密共享方法(Shamir’s secret sharing scheme)是一個可以將金鑰分割成多個部分的方法,分割之後的部分金鑰可以讓多人分開保存,在復原金鑰時,要湊足足夠數量的部分金鑰,才能將原始金鑰還原。
ssss 工具
ssss 是一個薩莫爾祕密共享方法指令工具,在 Ubuntu Linux 中可以使用 apt
安裝:
# 安裝 ssss 套件
sudo apt install ssss
安裝好 ssss
套件之後,我們可以使用 ssss-split
指令將金鑰分割成多份,在分割金鑰時,要以 -n
參數指定分割成幾份,同時以 -t
參數指定還原金鑰時至少需要湊足幾份:
# 分割金鑰,分割成 3 份,至少要其中 2 份才能復原 ssss-split -t 2 -n 3
Generating shares using a (2,3) scheme with dynamic security level. Enter the secret, at most 128 ASCII characters: Using a 144 bit security level. 1-4ccb5072cf714c5d7966f3dfc334f2f0cdd9 2-af25a2a2d421c84973f694b5698f4df104ea 3-f1800ced22ee4bba8a7949930fe6270e43f9
在執行 ssss-split
指令之後,會要求使用者從鍵盤輸入金鑰,然後就會輸出分割後的各部分金鑰內容,這時候就可以將這些部分的金鑰分給多人各自保管。
若要重建出原始的金鑰,可以使用 ssss-combine
指令,並以 -t
參數指定需要湊足的部分金鑰份數:
# 以 2 份部分金鑰進行復原 ssss-combine -t 2
Enter 2 shares separated by newlines: Share [1/2]: 1-4ccb5072cf714c5d7966f3dfc334f2f0cdd9 Share [2/2]: 2-af25a2a2d421c84973f694b5698f4df104ea Resulting secret: PASSWORD1234567890
加入名稱標示
如果我們同時需要使用 ssss 工具分割多把金鑰時,可以使用 -w
參數加上標示名稱,方便我們區分不同的部分金鑰:
# 加入名稱標示 ssss-split -t 2 -n 3 -w mypass
Generating shares using a (2,3) scheme with dynamic security level. Enter the secret, at most 128 ASCII characters: Using a 144 bit security level. mypass-1-f029c922af59eaf9539fb58d3801631ac216 mypass-2-d6e0900214708501260418109fe46e251be1 mypass-3-34a7a71d8297a056f572836402b89530533d
復原金鑰時,一樣連同名稱標示一起輸入即可:
# 以 2 份部分金鑰進行復原 ssss-combine -t 2
Enter 2 shares separated by newlines: Share [1/2]: mypass-1-f029c922af59eaf9539fb58d3801631ac216 Share [2/2]: mypass-2-d6e0900214708501260418109fe46e251be1 Resulting secret: PASSWORD1234567890
以 ssss 分割 AES 金鑰
AES 加密時所採用二進位的金鑰檔案,也可以使用 ssss 進行分割保存。假設我們使用亂數產生一個 256 位元的 AES 金鑰檔案,用於 AES-256 加密:
# 產生亂數金鑰 openssl rand 32 > my_aes.key # 使用金鑰檔案以 AES-256 方式搭配 CBC 模式加密 openssl enc -aes-256-cbc -pbkdf2 -pass file:./my_aes.key \ -in sample.txt -out sample.txt.enc # 使用金鑰檔案以 AES-256 方式搭配 CBC 模式解密 openssl enc -aes-256-cbc -d -pbkdf2 -pass file:./my_aes.key \ -in sample.txt.enc -out sample_decrypted.txt
我們可以使用 ssss-split
搭配 -x
參數,以十六進位模式分割這個 my_ses.key
金鑰檔案:
# 與 ssss-split 分割金鑰 xxd -p -c64 my_aes.key | ssss-split -t 2 -n 3 -x
Generating shares using a (2,3) scheme with dynamic security level. Enter the secret, as most 256 hex digits: Using a 256 bit security level. 1-cd37c41201a9da0e3c53be9150da7bb807a3f8272fbe57a7ee1ddb45d47553ac 2-e6e461b43605531126b3b0085edd00af4b221cf2c08401c739c1f1ec7eac064e 3-005502d6249ed41bd0ec4a7f5b2029a270a2bf419a6dcc188b75e874e71b36f1
還原金鑰時,可以將 ssss-combine
的輸出直接導入 xxd
轉為原始的二進位模式,輸入兩組部分金鑰之後,即可產生復原的 my_aes2.key
金鑰檔案:
# 以 ssss-combine 還原金鑰 ssss-combine -t 2 -x -q 2>&1 | xxd -p -r > my_aes2.key
1-cd37c41201a9da0e3c53be9150da7bb807a3f8272fbe57a7ee1ddb45d47553ac 2-e6e461b43605531126b3b0085edd00af4b221cf2c08401c739c1f1ec7eac064e
驗證金鑰檔案是否一致:
# 驗證金鑰檔案是否一致
md5sum my_aes.key my_aes2.key
dd2d04817af887b9f39ac7a15a9fae48 my_aes.key dd2d04817af887b9f39ac7a15a9fae48 my_aes2.key