
我有一個 shell 腳本和一個使用加密機制的 tcl 腳本,並且希望這兩個腳本有相同的密碼輸出。
例如,tcl腳本和shell腳本的輸出密碼應該相同。 (事實上我願意使用任何加密機制)
問題是兩個腳本都產生不同的密文。
在 tcl 中我使用以下命令:
[aes::aes -mode cbc -dir encrypt -key 1234567891012345 hi]
並在 shell 腳本中:
echo -n "hi" | openssl enc -aes-128-cbc -nosalt -pass pass:1234567891012345
我假設這兩個命令的結果是相同的,但事實並非如此。我正在起訴無鹽選項,因此如果命令執行兩次,則會從 shell 腳本產生相同的密碼。
有沒有辦法使用不同的腳本實現相同的密文?
答案1
如果您要求openssl enc
使用密碼,它始終透過 KDF 提供,而不會直接用作密鑰;使用-nosalt
不會停用此功能。 (您可以使用該openssl enc -p
選項查看實際使用的金鑰和 IV。)若要指定原始金鑰,您需要該-K
選項。
(請注意,該openssl enc -K
值預計為以十六進位表示,同時aes::aes -key
被解釋為原始二進位資料。
另一個問題是填充。由於 AES 是一種分組密碼,所有輸入資料必須被填充到 16 位元組(AES 區塊大小)的倍數,並且有多種具有不同安全屬性的填充方法。 Tclaes
模組使用簡單的零填充,以 0x00 位元組擴展資料。
同時,OpenSSL 使用 PKCS#7 填充,並使用與填充大小相符的值填充區塊。例如,如果您的輸入只有 2 個位元組,則需要 14 個位元組的填充,因此根據 PKCS#7,每個填充位元組的值也將為 14 (0x0E)。
(man enc
談到 PKCS#5,這是一個較舊的文檔,僅定義 8 位元組區塊的填充方案。PKCS#7 後來定義了完全相同的方案對於任何區塊大小.)
對於 CBC 模式,您還需要指定 IV(16 字節,等於 AES 區塊大小)。 Tcl 模組預設使用全零 IV。儘管 CBC 僅將 IV 用於第二個及以後的區塊,因此它不會影響短文本的輸出。
所以總而言之,這些會給你相同的結果(使用零填充):
aes::aes -mode cbc -dir encrypt -key 1234567891012345 -hex "hi"
printf 'hi\0\0\0\0\0\0\0\0\0\0\0\0\0\0' \
| openssl enc -aes-128-cbc -nopad \
-K 31323334353637383931303132333435 \
-iv 00000000000000000000000000000000 \
| hexdump -C
這些也是(使用 PKCS#7 填充):
aes::aes -mode cbc -dir encrypt -key 1234567891012345 -hex \
"hi\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e"
printf 'hi' \
| openssl enc -aes-128-cbc \
-K 31323334353637383931303132333435 \
-iv 00000000000000000000000000000000 \
| hexdump -C
若要實現填充:
set data "hi"
set pad [expr {16 - ([string length $data] % 16)}]
append data [string repeat [format %c $pad] $pad]
aes::aes -mode cbc -dir encrypt -key 1234567891012345 -hex $data