【问题标题】:Ruby/OpenSSL: decipher final throwsOpenSSL::Cipher::CipherError, padding = 0 won't solve itRuby/OpenSSL: decipher final throwsOpenSSL::Cipher::CipherError, padding = 0 不会解决它
【发布时间】:2018-03-06 16:32:35
【问题描述】:

我用以下代码加密了data 字符串:

cipher = OpenSSL::Cipher.new('aes-128-cbc')
cipher.encrypt
key = cipher.key = Digest::SHA256.hexdigest password
iv = cipher.random_iv
encrypted = cipher.update(data) + cipher.final

base64_iv = Base64.encode64 iv
base64_encrypted = Base64.encode64  encrypted

puts base64_iv
puts base64_encrypted
File.write  enc_iv_base64_filename, base64_iv
File.write  encrypted_base64_filename, base64_encrypted

我通常用这个程序破译:

decipher = OpenSSL::Cipher.new('aes-128-cbc')
decipher.decrypt
# decipher.padding = 0
decipher.key = Digest::SHA256.hexdigest password
decipher.iv = Base64.decode64 (File.read base64_iv)
plain = decipher.update(Base64.decode64(File.read base64_encrypted)) + decipher.final

它始终适用于我尝试使用包含小字符串的 data 的所有值。

现在我正在尝试使用包含约 500MB 文件内容的字符串,主要由“可读”字符组成(一个奇怪的事实是,拥有 1100MB 的可用内存是不够的,但在添加 2G 交换之后工作;对这个问题不重要=))。该文件被解密,上传到服务器,然后再次下载。通过尝试解密它,它抛出了这个异常:

:in `final': wrong final block length (OpenSSL::Cipher::CipherError)

然后,我注释掉了:

decipher.padding = 0

解密到最后——这表明ivkey等解密参数是正确的——但是,数据完全不可读——表明我遇到了问题编码。填充是否改变了data 字符串的解码方式?谁能确认文件只能在传输过程中损坏?谜题的答案是什么?

【问题讨论】:

    标签: ruby encoding openssl cryptography


    【解决方案1】:

    错误是任何key 都会破译密码,但只有正确的key 才能破译出与原始流类似的东西。

    在我的例子中,我使用了一个坏的password,它有不可见的字符。 password 之前已通过相同的程序破译。如果没有padding = 0,则用于正确生成的密码。添加padding = 0 后,在输出中添加了一些填充。请注意,puts 不会打印“不可见”字符,但 p 会。

    如何确保解密后的文本是原始密文仍然存在疑问。但是,问题本身已得到解答。

    【讨论】:

    • 至于最后一个疑问:使用经过身份验证的密码,例如 GCM 或单独的 MAC,例如 HMAC(在最后一种情况下,不要忘记对 IV 进行 MAC!)。
    • @MaartenBodewes:我正在考虑在流的开头添加一些 <length>L</length>。然后我可以使用padding = 0,并且在破译时我可以丢弃超过L的字符。你不认为我可以只修补我的程序吗?你觉得这有什么危险吗?
    猜你喜欢
    • 1970-01-01
    • 2014-03-20
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-23
    • 2014-02-24
    • 1970-01-01
    相关资源
    最近更新 更多