我正在开发一个跨语言项目,用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是兼容的,但这个假设是不正确的?任何帮助,我可以得到一个这将是最有帮助的。
答案 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个字符。