如何将 128 CFB 加密为 Ruby?

Posted

技术标签:

【中文标题】如何将 128 CFB 加密为 Ruby?【英文标题】:How can I mcrypt 128 CFB to Ruby? 【发布时间】:2014-12-10 21:36:45 【问题描述】:

我需要与加密请求和答案的 php API 进行交换。在我这边,我在 rails 4.0.0 (ruby 2.0),我无法让它工作。

我已经阅读了很多关于这个主题的答案,并试图了解 mcrypt 的工作原理,例如http://www.chilkatsoft.com/p/php_aes.asp,但没有成功。我仍然无法解密从 PHP 加密的内容或加密 PHP 可以解密的内容

你能帮我看看我做错了什么吗?

PHP 代码:

$secretKey = "1234567891234567";
$encrypt = urlencode( base64_encode( mcrypt_encrypt(
             MCRYPT_RIJNDAEL_128,
             md5($secretKey),
             $cleartext,
             MCRYPT_MODE_CFB,
             $secretKey
           ) ) );

$input = urldecode($input);
$decrypt = mcrypt_decrypt( MCRYPT_RIJNDAEL_128,
                           md5($secretKey),
                           base64_decode($input),
                           MCRYPT_MODE_CFB,
                           $secretKey );

Ruby 代码:

def self.encode(params = )
  cipher = OpenSSL::Cipher::AES.new(256, :CFB)
  cipher.encrypt
  cipher.key = Digest::MD5.hexdigest("1234567891234567")
  cipher.iv = "1234567891234567"
  encrypted = cipher.update(params.to_query) + cipher.final

  CGI.escape(Base64.strict_encode64(encrypted))
end

def self.decode(answer)
  decrypted = Base64.decode64(CGI.unescape(answer))

  decipher = OpenSSL::Cipher::AES.new(256, :CFB)
  decipher.decrypt
  decipher.key = Digest::MD5.hexdigest("1234567891234567")
  decipher.iv = "1234567891234567"
  decoded = decipher.update(decrypted) + decipher.final
end

【问题讨论】:

你有没有比较过 MD5 函数的输出,特别是如果它们是大写或小写的(如果这解决了问题,我想把它作为答案发布) 这是我的第一次检查,md5、Base64.encode64 和 urlencode。但记录:md5 php:fb77fc7f384d0c2bc555701e57a9e589 md5 ruby​​:fb77fc7f384d0c2bc555701e57a9e589 好吧,这让我很难过。我想我只能调试答案,但这意味着确保我的 PHP 和 Ruby 解释器已启动并正在运行……已经投票了。 这可能对你有帮助:***.com/questions/21485437/… 似乎您使用的是不同的块大小,即 php 中的 128 位和 ruby​​ 中的 256 位。尝试将 AES.new(256, :CFB) 更改为 AES.new(128, :CFB) .. 【参考方案1】:

您必须在 PHP 代码中使用 'ncfb' 而不是 MCRYPT_MODE_CFB。 PHP 默认为 8 位反馈,而不是完整块大小的反馈。

或者,您可以指定:CFB8 以与Ruby 中的PHP 兼容。这是我在阅读 OpenSSL 文档中的 CFB 文档后猜到的。

非常感谢this Q/A on IT security,因为我知道自己在寻找什么。

【讨论】:

ncfb - 即应首选 128 位反馈。 非常感谢!!!我把 :CFB8 放在我的 ruby​​ 代码中,它工作得很好,因为我不是 PHP 代码的所有者。再次感谢您对此的帮助! @Stephanie 很高兴它为你解决了,斯蒂芬妮。是的,这就是我编辑答案的原因,经常发生一侧基本上是预定义的并且无法更改。【参考方案2】:

看看https://github.com/kingpong/ruby-mcrypt

在你的 gem 文件中添加

gem "ruby-mcrypt", :lib => "mcrypt"

用法

crypto = Mcrypt.new(:twofish, :cbc, MY_KEY, MY_IV, :pkcs)

# encryption and decryption in one step
ciphertext = crypto.encrypt(plaintext)
plaintext  = crypto.decrypt(ciphertext)

# encrypt in smaller steps
while chunk = $stdin.read(4096)
  $stdout << crypto.encrypt_more(chunk)
end
$stdout << crypto.encrypt_finish

# or decrypt:
while chunk = $stdin.read(4096)
  $stdout << crypto.decrypt_more(chunk)
end
$stdout << crypto.decrypt_finish

您也可以查看https://***.com/a/21489711/1380867

【讨论】:

哦,等等,现在我看到你在展示什么了。为 Ruby 使用 mcrypt 很好(OpenSSL 维护得更好,但我想如果你在 PHP 中使用 mcrypt ......)。但是,如果您指定 twofish、CBC 和 PKCS 填充,您目前不匹配问题中的加密货币。

以上是关于如何将 128 CFB 加密为 Ruby?的主要内容,如果未能解决你的问题,请参考以下文章

OpenSSL AES_cfb128_encrypt C++

常见对称加密

07.对称加密算法指令

ecshop的aes加密(封装)

对称加密php

在 PHP 中匹配 128 个字符的密码哈希 - 使用 Ruby on Rails 加密