介紹使用 OpenSSL 指令進行對稱式、非對稱式加密與解密的方法與實際範例。
對稱式加密(symmetric encryption)簡單來說就是使用一組密碼來加密檔案,而解密時也是使用同一組密碼,操作流程簡單,但是安全性較低。
假設原始資料檔案是 plaintext.txt
,我們可以使用以下 openssl
指令將 plaintext.txt
以 AES256 演算法搭配使用者輸入的密碼加密檔案內容,並將加密後的內容以 base64 編碼之後,儲存於 encrypted.txt
檔案中。
# 使用 OpenSSL 搭配 AES256 加密檔案(以 Base64 編碼) openssl aes-256-cbc -pbkdf2 -salt -a -e -in plaintext.txt -out encrypted.txt
enter aes-256-cbc encryption password: Verifying - enter aes-256-cbc encryption password:
在加密之前,openssl
會以互動式的方式詢問使用者加密用的密碼,輸入兩次相同的密碼之後,就會以這組密碼進行加密。
若要對上面加密後產生的 encrypted.txt
進行解密,可以使用以下指令:
# 使用 OpenSSL 搭配 AES256 解密檔案(以 Base64 編碼) openssl aes-256-cbc -pbkdf2 -salt -a -d -in encrypted.txt -out plaintext.txt
enter aes-256-cbc decryption password:
以 base64 編碼的檔案會比較大,若要節省空間,可以將 -a
參數移除,改用二進位的方式存放加密檔案:
# 使用 OpenSSL 搭配 AES256 加密檔案(以二進位編碼) openssl aes-256-cbc -pbkdf2 -salt -e -in plaintext.txt -out encrypted.bin
解密方式也都類似:
# 使用 OpenSSL 搭配 AES256 解密檔案(以二進位編碼) openssl aes-256-cbc -pbkdf2 -salt -d -in encrypted.bin -out plaintext.txt
非對稱式加密(asymmetric encryption)也稱為公開金鑰加密,在使用前要準備好一對私鑰與公鑰,使用公鑰進行檔案的加密,解密時則使用私鑰,操作上較複雜,但是安全性較佳。
在使用 RSA 非對稱式加密之前,先產生一支長度為 8912 位元的 RSA 私鑰,儲存於 private.key
,並以 AES256 加密保護這支私鑰。
# 產生 8912 位元的 RSA 私鑰,以 AES256 加密保護 openssl genrsa -aes256 -out private.key 8912
Generating RSA private key, 8912 bit long modulus (2 primes) ..............................................................................................................................................................................................................................................................................................................................................................................................+++ ..................................................................+++ e is 65537 (0x010001) Enter pass phrase for private.key: Verifying - Enter pass phrase for private.key:
這裡我們指定金鑰長度為 8912 位元,長度越長安全性越高。
再以 RSA 私鑰來產生 RSA 公鑰:
# 從 RSA 私鑰產生 RSA 公鑰 openssl rsa -in private.key -pubout -out public.key
Enter pass phrase for private.key: writing RSA key
準備好一對 RSA 私鑰與公鑰之後,接著就可以用公鑰來進行檔案的加密:
# 以 RSA 公鑰加密檔案 openssl rsautl -encrypt -pubin -inkey public.key -in plaintext.txt -out encrypted.bin
上面這行指令會將 plaintext.txt
加密成 encrypted.bin
。
若要對 encrypted.bin
進行解密,就要使用私鑰:
# 以 RSA 公鑰解密檔案 openssl rsautl -decrypt -inkey private.key -in encrypted.bin -out plaintext.txt
Enter pass phrase for private.key:
解密時由於鑰使用到私鑰,需要先輸入密碼將私鑰解開,再以私鑰解密檔案。
openssl
的 rsautl
功能無法對大型檔案進行加密,如果資料量較大時,需要改用 RSA + AES 的混合加密方式。
Step 1
由接收端產生 RSA 私鑰與公鑰。
# 產生 8912 位元的 RSA 私鑰,以 AES256 加密保護(接收端) openssl genrsa -aes256 -out private.pem 8912 # 從 RSA 私鑰產生 RSA 公鑰(接收端) openssl rsa -in private.pem -pubout -out public.pem
Step 2
將 RSA 公鑰 public.pem
傳送至發送端。
Step 3
在發送端隨機產生一串 AES 加密用的高強度密碼,儲存於檔案中,並將此密碼檔案透過 RSA 公鑰加密。
# 產生 AES 加密用的高強度密碼(發送端) openssl rand -out key.bin 32 # 加密密碼檔(發送端) openssl rsautl -encrypt -pubin -inkey public.pem -in key.bin -out key.bin.enc
Step 4
使用密碼檔案中的高強度密碼,配合 AES 演算法加密加密大型檔案。
# 加密大型檔案(發送端) openssl aes-256-cbc -pbkdf2 -salt -e -in large.file \ -out large.file.enc -pass file:./key.bin
這裡使用 -pass
讀取密碼檔時,根據手冊說明,只會讀取密碼檔案中的第一行,所以可能對於二進位檔案會有讀取不完全的問題。
Step 5
將 key.bin.enc
與 large.file.enc
兩個加密後的檔案傳送至接收端。
Step 6
接收端以 RSA 私鑰解密密碼檔,再透過密碼檔搭配 AES 解密大型檔案。
# 解密密碼檔(接收端) openssl rsautl -decrypt -inkey private.pem -in key.bin.enc -out key.bin # 解密大型檔案(接收端) openssl aes-256-cbc -pbkdf2 -salt -d -in large.file.enc \ -out large.file -pass file:./key.bin