使用DES-CBC的Ruby OpenSSL加密结果不正确

axkjgtzd  于 2022-09-21  发布在  Ruby
关注(0)|答案(1)|浏览(213)

我正在尝试使用openssl:https://emvlab.org/descalc/?key=18074F7ADD44C903&iv=18074F7ADD44C903&input=4E5A56564F4C563230313641454E5300&mode=cbc&action=Encrypt&output=25C843BA5C043FFFB50F76E43A211F8D在Ruby中复制加密结果

  • 原始字符串=“NZVOLV2016AENS”
  • 字符串转换为十六进制=“4e5a56564f4c563230313641454e53”
  • IV=“18074F7ADD44C903”
  • Key=“18074F7ADD44C903”
  • 预期结果=“9B699B4C59F1444E8D37806FA9D15F81”

以下是我的Ruby代码:

  1. require 'openssl'
  2. require "base64"
  3. include Base64
  4. iv = "08074F7ADD44C903"
  5. cipher = "08074F7ADD44C903"
  6. def encode(string)
  7. puts "Attempting encryption - Input: #{string}"
  8. encrypt = OpenSSL::Cipher.new('DES-CBC')
  9. encrypt.encrypt
  10. encrypt.key = ["18074F7ADD44C903"].pack('H*') #.scan(/../).map{|b|b.hex}.pack('c*')
  11. encrypt.iv = ["18074F7ADD44C903"].pack('H*')
  12. result = encrypt.update(string) + encrypt.final
  13. puts "Raw output: #{result.inspect}"
  14. unpacked = result.unpack('H*')[0]
  15. puts "Encrypted key is: #{unpacked}"
  16. puts "Encrypted Should be: 9B699B4C59F1444E8D37806FA9D15F81"
  17. return unpacked
  18. end
  19. res = encode("NZVVOLV2016AENS")
  1. Output:
  2. Encrypted key is: 9b699b4c59f1444ea723ab91e89c023a
  3. Encrypted Should be: 9B699B4C59F1444E8D37806FA9D15F81

有趣的是,结果的前半部分是正确的,后16位是错误的。

5t7ly7z5

5t7ly7z51#

网站默认使用零填充,而Ruby代码默认使用PKCS#7填充。
Ruby似乎不支持零填充,所以禁用默认填充并自己实现零填充。
值为0x00的下一个完整块大小的零填充填充。DES的块大小为8字节。如果明文的最后一块已经填充,则不进行填充:

  1. def zeroPad(string, blocksize)
  2. len = string.bytes.length
  3. padLen = (blocksize - len % blocksize) % blocksize
  4. string += "0" * padLen
  5. return string
  6. end

encode()函数(最好称为encrypt()函数)中,在加密之前必须添加以下行:

  1. encrypt.padding = 0 # disable PKCS#7 padding
  2. string = zeroPad(string, 8) # enable Zero padding

然后,修改后的Ruby代码提供与网站相同的密文。

请注意,DES是不安全的,使用密钥作为IV(以及静态IV)也是不安全的。此外,与PKCS#7填充相比,零填充是不可靠的。

展开查看全部

相关问题