【问题标题】:Reading data encrypted with PHP using Ruby使用 Ruby 读取 PHP 加密的数据
【发布时间】:2014-06-24 09:44:42
【问题描述】:

我正在用 Ruby 替换旧的 PHP 系统。这里的开发人员为我编写了自己的加密代码(呃)。旧的 PHP 使用下面的代码来加密一些数据。我很难用 ruby​​ 编写“解密”方法。

前言
我知道这个现有的 php 代码存在安全问题(三重奏、无盐等)。新的 Ruby 代码不存储任何敏感数据,但至少需要读取 PHP 创建的数据。

旧 PHP 代码

// old PHP code
class encrypter {
  private $_crypt;
  private $_key;
  private $_algorithm;
  private $_mode;
  private $_init_vector;


    public function __construct( $key = 'SomeRandomStringThisOneIsOK', $algorithm = 'tripledes', $mode = 'ecb', $init_vector = false ) {
      $this->_key = $key;
      $this->_algorithm = $algorithm;
      $this->_mode = $mode;
      $this->_init_vector = $init_vector;
      $this->_crypt = mcrypt_module_open($algorithm, '', $mode, '') ;
      $random_seed = MCRYPT_RAND;
      //generate an initialization vector if none is given.
      $init_vector = ($init_vector === false)
        ? mcrypt_create_iv(mcrypt_enc_get_iv_size($this->_crypt), $random_seed)
        : substr($init_vector, 0, mcrypt_enc_get_iv_size($this->_crypt));

      $expected_key_size = mcrypt_enc_get_key_size($this->_crypt);

      // we dont need to know the real key, we just need to be able to confirm a hashed version
      $key = substr(md5($key), 0, $expected_key_size);

      mcrypt_generic_init($this->_crypt, $key, $init_vector);
    }


    public function encrypt($plain_string) {
      return base64_encode(mcrypt_generic($this->_crypt, $plain_string));
    }

    public function decrypt($encrypted_string) {
      return trim(mdecrypt_generic($this->_crypt, base64_decode($encrypted_string)));
    }

    public function __destruct() {
      $this->_crypt = null;
    }

    public function __sleep() {
      $this->_crypt = null;
      return array_keys( get_object_vars( $this ) );
    }

    public function __wakeup () {
      $this->__construct($this->_key, $this->_algorithm, $this->_mode, $this->_init_vector);
    }
  }

我不明白的地方
我不知道如何在 Ruby 中模拟这行 php。诚然,因为我不确定 100% php 在做什么。

mcrypt_create_iv(mcrypt_enc_get_iv_size($this->_crypt), $random_seed)

我目前拥有的 Ruby
我正计划使用 Encryptor Gem(它包装了 OpenSSL 方法)。我无法在 OS X 上安装 ruby​​-mcrypt,并且认为 OpenSSL 是内置的,所以为什么不使用它。同样,我只需要能够解密数据。

secret = "some_secret_key"
iv = "what goes here?"
Encryptor.default_options.merge!(:algorithm => 'des-ede-cbc', :key => secret)
decrypted_value = Encryptor.decrypt(:value => encrypted_value, :key => secret, :iv => iv)

【问题讨论】:

    标签: php ruby encryption openssl mcrypt


    【解决方案1】:

    您突出显示的行创建了一个新的随机初始化向量 (IV),用于播种一些加密货币。 IV 的长度取决于所使用的算法,mcrypt_enc_get_iv_size 返回所使用算法的正确长度。

    要解密数据,您需要提供用于加密消息的相同初始化向量。你不能从代码中得到这个,因为它每次都会生成一个新的随机源,尽管使用了相当周的随机源(如果没有明确传递给构造函数)。

    【讨论】:

      【解决方案2】:

      iv = "这里发生了什么?"

      我相信答案是:

      $init_vector = ($init_vector === false)
          ? mcrypt_create_iv(mcrypt_enc_get_iv_size($this->_crypt), $random_seed)
          : substr($init_vector, 0, mcrypt_enc_get_iv_size($this->_crypt));
      

      如果init_vectorfalse,则创建一个随机的iv。否则,使用传递给函数__constructiv

      正如 Frederick 所说,初始化向量的大小取决于所使用的分组密码,可以通过 mcrypt_enc_get_iv_size 获取。

      您已经展示了encryptor 类。 decryptor 类会有点不同。它将使用现有的iv。它不会创建一个,所以应该缺少逻辑。


      只是自行车脱落,但这有点弱:

      $key = substr(md5($key), 0, $expected_key_size);
      

      有更好的方法来扩展和提取熵。

      Information Security Stack ExchangeCrypto Stack Exchange 上的人们应该能够帮助使用熵提取器。他们可能会告诉您使用PBKDFHKDF 或使用HMAC 而不仅仅是MD5MD5不是伪随机排列或 PRP 函数;而@ 987654339@拥有财产)。

      【讨论】:

        【解决方案3】:

        我终于能够通过使用以下红宝石来完成这项工作。我不是 100% 确定为什么,但是 Ruby 库不需要 IV。

        Mcrypt.new(:tripledes, :ecb, Digest::MD5.hexdigest(key)[0,24])
        plaintext  = crypto.decrypt(Base64.decode64('some_encryped_base_64_encoded_string')).strip
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-11-10
          • 1970-01-01
          • 1970-01-01
          • 2012-11-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-22
          相关资源
          最近更新 更多