使用Ruby读取使用PHP加密的数据

时间:2014-05-07 12:08:36

标签: php ruby encryption openssl mcrypt

我正在使用Ruby替换旧的PHP系统。这里的开发人员为我编写了自己的加密代码(ugh)。旧的PHP使用以下代码来加密某些数据。我正在艰难地写一个"解密"红宝石中的方法。

前言
我已经意识到这个现有的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%正在做什么。

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)

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

  

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。否则,使用传递给函数iv的{​​{1}}。

正如Frederick所说,初始化向量的大小基于正在使用的分组密码,并且可以使用__construct获取。

您已展示mcrypt_enc_get_iv_size课程。 encryptor课程会有所不同。它将使用现有的decryptor。它将创建一个,因此逻辑应该丢失。


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

iv

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

Information Security Stack ExchangeCrypto Stack Exchange上的人应该能够帮助使用熵提取器。他们可能会告诉您使用$key = substr(md5($key), 0, $expected_key_size); PBKDF或使用HKDF而不只是HMACMD5 a伪随机置换或PRP函数;而MD5拥有属性)。

答案 2 :(得分:0)

我终于通过使用以下ruby来实现这一点。我不是100%确定原因,但Ruby lib不需要IV。

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