【问题标题】:Encrypt a string using Triple Data encryption standard(3DES) with PKCS7 padding使用带有 PKCS7 填充的三重数据加密标准 (3DES) 加密字符串
【发布时间】:2020-04-01 06:45:53
【问题描述】:

要求:

我有一个 Ruby on rails 应用程序,我需要执行以下操作。

以下字符串应使用 3DES 算法和工作密钥进行加密。 ABJGTU9 的加密值为 vV51P0OGXt0=

工作密钥是 A5157A0D77B24AEA868AD73288366826

以下文档中提到的 3DES 算法使用以下步骤进行数据加密: 一世。使用具有 CBC 密码模式和 PKCS7 填充的密钥的左侧部分加密数据。 ii.使用具有 CBC 密码模式且无填充的密钥的右侧部分解密数据。 iii.使用具有 CBC 密码模式且不填充的密钥的左侧部分加密数据。

我尝试了以下article 这就是我所做的,我的输出是 "hsYUuA/Mo6A=\n" 预期是 vV51P0OGXt0=

  cipher = OpenSSL::Cipher::Cipher.new('DES-EDE3-CBC')
  cipher.encrypt # Must be called before anything else

  # Generate the key and initialization vector for the algorithm.
  # Alternatively, you can specify the initialization vector and cipher key
  # specifically using `cipher.iv = 'some iv'` and `cipher.key = 'some key'`
  # cipher.pkcs5_keyivgen('SOME_PASS_PHRASE_GOES_HERE')

  key = Digest::MD5.base64digest('A5157A0D77B24AEA')
  cipher.key = key
  data = "ABJGTU9"
  output = cipher.update(data)
  output << cipher.final
  output
end

我不确定我是否走对了。

【问题讨论】:

  • 您提供的工作密钥很可能就是密钥;即您不应该执行 MD5 步骤。编辑(更详细):MD5 步骤通常用于将文本密码转换为特定大小的字节数组。您提供的工作密钥看起来像 16 字节编码为十六进制。
  • 另外;由于 IV 不同,您的输出可能与预期不同。我不知道Ruby的具体情况;但要确保 IV 匹配(我猜你错过了指定 IV 的步骤)
  • @clausc 密码的密钥应该是 24 字节,所以我使用了 MD5 base64 摘要,它给了我预期的大小,但正如你提到的,iv 可能是一个问题,我会检查一下跨度>
  • 请注意,您的描述是:用左边部分加密;用正确的部分解密。带有 EDE 的 3DES 可以为此使用 16 字节密钥 - 事实上,这与您的描述完全匹配。参见en.wikipedia.org/wiki/Triple_DES,键控选项 2
  • @clausc 他们甚至在发送加密之前就输入密钥,就像这样CryptoJS.enc.Hex.parse(sec.substr(0, len));我现在有整个加密js

标签: ruby-on-rails encryption cryptography


【解决方案1】:

问题中提到的方案有很多错误:

  1. 密钥是两密钥三重DES密钥,需要十六进制解码,不要对其进行MD5;
  2. 如果您的代码不能使用如图所示的 128 位 DES 密钥,您应该复制前 8 个字节并将它们附加到密钥的末尾(因此 DES 密钥 1 和 DES 密钥 3 是相同的) - 然而,OpenSSL 应该可以很好地处理 16 字节的密钥;
  3. 步骤 i、ii 和 iii 中描述的加密方法仅适用于需要加密的每个单独的 - 如果您已经使用密码 'DES-EDE3-CBC',则不需要它。

默认情况下,OpenSSL 已经使用 PKCS#7 填充进行填充,因此没有理由为此做任何特别的事情。

CBC 要求使用相同密钥的每个加密操作都有一个唯一的、不可预测的 IV,而描述的方案中似乎缺少这一点。

【讨论】:

  • var key1 = CryptoJS.enc.Hex.parse(sec.substr(0, len)); input = CryptoJS.enc.Utf8.parse(input); var result = CryptoJS.TripleDES.encrypt(input, key1, { mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, iv: iv });
  • 这是第一部分的完成方式,提到的,同样的方式 2 和 3 完成。这里 sec 是工作密钥。
猜你喜欢
  • 2017-08-29
  • 2011-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-24
  • 2021-01-04
相关资源
最近更新 更多