1

我正在尝试对一些数据进行 AES 加密,并使用它random_iv来生成初始化向量。

def encrypt (data)
    cipher = OpenSSL::Cipher::AES.new(256, :CBC)
    cipher.encrypt
    cipher.key = @key
    iv = cipher.random_iv
    encrypted = cipher.update(data) + cipher.final
    encoded = Base64.encode64(encrypted+iv) 
    return encoded, self.sign(encoded)
end

如果ivcontains ',则编码的字符串在那里结束,之后的所有内容都'将被忽略。我认为random_ivOpenSSL::Random.random_bytes(16),还没有检查来源。当我得到random_iv这样的:

"0\xC8x'6\x86\x06\xFEG[\xCE\xF5\xF5\xCBL>"

编码字符串的最后 16 个字符与它完全不同(结束于C8)。

Base64.decode64('1JCQvhD6mrDXkhW4Hn9HIIr32TmYlBmp803oxOtrZMg=\n')[-16,16]
# => "\x8A\xF7\xD99\x98\x94\x19\xA9\xF3M\xE8\xC4\xEBkd\xC8" 

如果没有'in iv,它工作正常。现在,我正在像这样解决这个问题:

cipher.iv = Digest::MD5.new.digest(cipher.random_iv)

因为MD5也是16byte,并且符合iv要求。

Digest::MD5.new.digest('test').bytesize
# => 16 

想知道是否有更好的方法来做到这一点。为什么首先'存在random_iv?我应该如何转义传递给的数据encode64

另外,我是否需要将字节附加到我的数据中,直到data.bytesize可以被 整除16?还是Cipher::AES为我做?

cipher.update(data)
4

1 回答 1

3

'作为字符串的内容没有什么特别之处。它只是一个 ASCII 值为 39 的字节。

在语句encoded = Base64.encode64(encrypted+iv)中,与您之前设置的两行iv不同的变量。cipher.iv您在名为 的范围内有方法或访问器iv吗?您的 base64 字符串'1JCQvhD6mrDXkhW4Hn9HIIr32TmYlBmp803oxOtrZMg=\n'(我认为是您的函数的结果)不会以您的示例 iv 的 base64 编码结束,所以我非常有信心+iv表达式的部分没有看到"0\xC8x'6\x86\x06\xFEG[\xCE\xF5\xF5\xCBL>"

您的示例 iv 的 base64 编码为我成功往返:

irb> iv = "0\xC8x'6\x86\x06\xFEG[\xCE\xF5\xF5\xCBL>".force_encoding('BINARY') 
=> "0\xC8x'6\x86\x06\xFEG[\xCE\xF5\xF5\xCBL>"
irb> e = Base64.encode64 iv
=> "MMh4JzaGBv5HW8719ctMPg==\n"
irb> d = Base64.decode64 e
=> "0\xC8x'6\x86\x06\xFEG[\xCE\xF5\xF5\xCBL>"
irb> d == iv
=> true
于 2013-02-11T07:57:26.067 回答