-1

密码的源字符串是否有最小长度?我正在尝试创建唯一的会话 ID,并且正在执行以下操作:

cipherer = OpenSSL::Cipher::Cipher.new("aes-256-cbc").encrypt

cipherer.update(Time.now.to_f.*(1000).to_i.to_s(36))

但它返回一个空字符串。我将乘法因子更改1000为更大的,例如100000000000000,然后它有时返回一个空字符串,有时返回一个长字符串。我想这是因为短于某个长度的字符串被密码映射到空字符串。这种理解正确吗?如果是这样,最小长度是多少,我怎样才能使它永远不会返回空字符串?我不需要破译它,所以不用担心舍入错误或硬件依赖性是否会导致无法破译。

4

1 回答 1

2

AES 块大小为 128 位 = 16 字节,即 16 个字符。这意味着 16 个字节输入和 16 个字节输出。

您正在通过调用来使用流模式OpenSSL::Cipher#update。这意味着该update方法的输入将附加到密码的输入,直到达到至少 16 个字节。只有这样,才能执行加密,然后该方法才会返回实际值。

这意味着,update如果您使用 8 Bytes 值提供调用,则只会每秒钟产生一次输出,这就是您所做的:

cipherer = OpenSSL::Cipher::Cipher.new("aes-256-cbc").encrypt
#=> #<OpenSSL::Cipher::Cipher:0x007fb67426e558>
cipherer.update('X'*8)
#=> ""
cipherer.update('X'*8)
#=> "\xA0+\xD8Y\xA5\xBC68\x972\x86!\xC7\xE5\xA2\xDE"
cipherer.update('X'*8)
#=> ""
cipherer.update('X'*8)
#=> "\xFB\xB1I\xE2\x01\xB8Z\x10\xDC\x96m?\xC3\x00\x19+"

另一方面,如果您提供一个 32 字节的值,两个块将同时被加密,例如

cipherer = OpenSSL::Cipher::Cipher.new("aes-256-cbc").encrypt
=> #<OpenSSL::Cipher::Cipher:0x007fb6741579f8>
cipherer.update('X'*32)
#=> "\xA0+\xD8Y\xA5\xBC68\x972\x86!\xC7\xE5\xA2\xDE\xFB\xB1I\xE2\x01\xB8Z\x10\xDC\x96m?\xC3\x00\x19+"
cipherer.update('X'*32)
#=> "\xB2!\xBA>M\x13t\xEBv^\xCE\xAE\x18\x9A\xE3S\xD96\x95\x89\xC1\xB4\xAA\xDD\xD3\xDCp\e<\x90\xA79"
cipherer.update('X'*32)
#=> "\x95\xA3-\xB9\x93D\x1D\xC0\xB3mh\xE3\xB5N\x9C\x8C\xEA\xF3\x80\xD3\xBDU\xCB'\xC0E\xDA\x02\xA8L\a\xB3"

解决问题的直接方法是使用保证为 16 字节长的字符串作为输入。

不过,我强烈建议您使用 ruby​​ 附带的 UUID 实现。在实施加密货币时有很多事情要考虑。你总是最好坚持标准并使用众所周知的、广泛使用的和经过实战考验的实现。也就是说,这是获取 UUID 的方法:

require 'securerandom'

SecureRandom.uuid
#=> "c5059a24-25fc-4617-aaf7-280df52cd8d3"

就那么简单。

于 2013-03-28T00:31:30.607 回答