用PHP加密(mcrypt),在Ruby中解密(OpenSSL :: Cipher)

时间:2014-01-31 16:45:33

标签: php ruby encryption mcrypt

我正在开发一个跨语言项目,用PHP包装ruby / Sinatra API,供其他团队使用。 API公开的信息都不敏感,但我们希望一个不经意的观察者不能轻易地访问它。

    private function generateSliceIDToken($key){
    $currentEpoch = time();
    $ivSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
    $iv = mcrypt_create_iv($ivSize, MCRYPT_RAND);
    $encryptedBytes = mcrypt_encrypt(
        MCRYPT_RIJNDAEL_128,
        $key,
        $currentEpoch.**Passcode**,
        MCRYPT_MODE_CBC, $iv
    );
    $ivAndEncryptedBytes = $iv . $encryptedBytes;

    return urlencode(urlencode(base64_encode($ivAndEncryptedBytes)));

上面的代码使用mcrypt的RIJNDAEL实现加密密码和时间戳,并对其进行编码以发送到ruby API

if identifier.validate_token Base64.decode64(URI.unescape( URI.unescape(params[:token])))

Sinatra抓住它并解码它

def validate_token(token)
  cipher = OpenSSL::Cipher::AES.new(128, 'CBC')
  cipher.decrypt
  cipher.key = **key**
  cipher.iv = token[0,16]

  plain = cipher.update(token[16..-1]) + cipher.final
  return plain[10,8] == **Passcode**
end

并将其传递给解密

问题是,解密失败并出现'Bad Decrypt'错误

我认为Mcrypt的RIJNDAEL和Cipher的AES是兼容的,但这个假设是不正确的?任何帮助,我可以得到一个这将是最有帮助的。

1 个答案:

答案 0 :(得分:3)

  

我认为Mcrypt的RIJNDAEL和Cipher的AES兼容,但是这个假设不正确吗?

您需要稍微调整正在编码的数据以使其与AES兼容。数据必须正确填充,字符和数量取决于其当前宽度:

$encode = $currentEpoch.'**Passcode**';
$len = strlen($encode);
$pad = 16 - ($len % 16);
$encode .= str_repeat(chr($pad), $pad);

还要记住$key长度恰好是16个字符。如果它更短,ruby抛出CipherError,而php pad键为空字节。如果它更长,ruby只使用前16个字符,但php再次填充它,并使用最后16个字符。