【问题标题】:OpenSSL decrypt AES 256bit (base64) encrypted password - wrong final block lengthOpenSSL 解密 AES 256 位(base64)加密密码 - 最终块长度错误
【发布时间】:2018-09-25 07:43:20
【问题描述】:

我正在尝试使用 OpenSSL 解密 aes-256-cdc 编码的密码

#!/usr/bin/env bash

ak=BgL0cPoZQ4wZWOWl5mXBhlMsNbbZL2zvsWZXjuGy4Iw=
iv=cGEvcGWzE8t7CS3wbeoUFQ==
pass=RCQm23YHOCg3nxOl7CcQ7w==

#change format from base64 into hex
AES_KEY=$(echo "${ak}" | openssl base64 -d | xxd -p |tr -d '\n')
AES_IV=$(echo "${iv}" | openssl base64 -d | xxd -p)
ENCODED_PASSWORD=$(echo "${pass}" | openssl base64 -d | xxd -p)

echo "AES_KEY ${AES_KEY}"
echo "AES_IV ${AES_IV}"
echo "ENCODED_PASSWORD ${ENCODED_PASSWORD}"

#set password file
echo "${ENCODED_PASSWORD}" > in.txt

#decode password
openssl enc -nosalt -aes-256-cbc -d -iv ${AES_IV} -K ${AES_KEY} -in in.txt

这会导致错误消息

AES_KEY 0602f470fa19438c1958e5a5e665c186532c35b6d92f6cefb166578ee1b2e08c
AES_IV 70612f7065b313cb7b092df06dea1415
ENCODED_PASSWORD 53b7adff6e85baedfa9dab80109ad67d
▒▒▒▒▒▒`$;▒▒▒▒%▒O▒Q▒▒▒S▒▒<7 7
                            bad decrypt
32624:error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length:evp_enc.c:518:
0602f470fa19438c1958e5a5e665c186532c35b6d92f6cefb166578ee1b2
e08c

我认为问题出在 aes-key (ak) 中,其中有一个换行符,我试图用

删除它
|tr -d '\n'

密码应该解码为

password

【问题讨论】:

  • $(echo $ak | openssl base64 -d | xxd -p -c32) 将给出没有麻烦的换行符的十六进制。同样openssl enc可以在解密时解码base64,而-nosalt对于非PBE会被忽略,所以只需echo $pass | openssl enc -aes-256-cbc -d -a -K $key -iv $iv

标签: bash encryption openssl aes


【解决方案1】:

如果您的 $pass 很长(可能超过 32 个字符),请务必使用 openssl -A 选项,原因在 openssl 手册中记录。 使用 -A 选项,对于加密,base64 编码的字符串不会被分割成段;对于解密,读取整行以使用 base64 进行解码。

代码示例:

plaintxt='hello world"
pass=$(echo ${plaintxt} | openssl enc -aes-128-cbc  -a -K ${AES_KEY} -iv ${AES_IV} -A )    
echo "decoded password is: "
echo ${pass} | openssl enc -aes-128-cbc -d -a -K ${AES_KEY} -iv ${AES_IV} -A

【讨论】:

    【解决方案2】:

    不,问题是in.txt 的编码。它根本不应该是文本,应该是二进制

    原则上,如果您使用echo -n 抑制密文中的最终行尾,您也不会收到此错误。然而,解密仍然会失败,因为它需要二进制而不是 编码 二进制值。

    如果要保留文件,您可能需要将 in.txt 的名称更改为 in.bin。您还应该能够使用标准输入 (stdin) 将密文简单地通过管道传输到 openssl。在这种情况下,您可能需要先对其进行编码以将其存储在 shell 变量中,然后 decode 然后再将其传送到 openssl 以对其进行解密。

    对于二进制,使用cat 而不是echo

    【讨论】:

    • 不,不要将二进制数据保存在 shell 变量中;如果它恰好包含 null 大多数 shell 将直接截断它,即使 shell 不包含,尝试将它传递给程序总是会。一些 shell 也可能会混淆其他“异常”字节。此外,并非所有版本的echo 都支持-n,并且在某些版本中,恰好包含 0x5c 的值将被破坏。 file 中的二进制文件在当今几乎所有系统上都是安全的,否则最好使用十六进制并对其进行解码,例如xxd -r -p,或者使用enc -a/--base64加密时base64编码,解密时解码。
    • 谢谢戴夫,调整后的答案 - 像往常一样:)
    【解决方案3】:

    这按预期工作:

    #!/usr/bin/env bash
    #base64 encoded aes key, iv and password
    ak=BgL0cPoZQ4wZWOWl5mXBhlMsNbbZL2zvsWZXjuGy4Iw=
    iv=cGEvcGWzE8t7CS3wbeoUFQ==
    pass=OfOXO+ruKFTCsBwGHynXwA==
    
    #change format from base64 into hex, for openssl to consume, xxd -p -c32 is taking care of wrapping of the new lines
    AES_KEY=$(echo ${ak} | openssl base64 -d | xxd -p -c32)
    AES_IV=$(echo ${iv} | openssl base64 -d | xxd -p -c32)
    
    echo "AES_KEY ${ak}"
    echo "AES_IV ${iv}"
    echo "encoded password ${pass}"
    echo "decoded password is: "
    echo ${pass} | openssl enc -aes-256-cbc -d -a -K ${AES_KEY} -iv ${AES_IV}
    

    解释:

    openssl enc -aes-256-cbc -d
    

    使用 aes-256-cbc 算法解码

    -a   
    

    在我们的例子中,这意味着 openssl 将接受 base64 编码的密码

    -K 
    

    aes 键

    -iv
    

    aes iv

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-30
      • 2018-09-09
      • 2020-01-20
      • 2014-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多