我正在开发一个跨语言项目,将 ruby/Sinatra API 封装在 PHP 中以供另一个团队使用。 API 公开的信息均不敏感,但我们希望猜测 URL 的临时观察者不易访问这些信息。
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
并将其传递给解密
问题是,解密失败并出现“错误解密”错误
我被引导相信 Mcrypt 的 RIJNDAEL 和 Cipher 的 AES 是兼容的,但这个假设不正确吗?我能得到的任何帮助都会是最有帮助的。
最佳答案
I was lead to believe Mcrypt's RIJNDAEL and Cipher's AES were compatible, but is this assumption incorrect?
您需要稍微调整正在编码的数据以使其兼容 AES。数据必须正确填充,字符和数量取决于其当前宽度:
$encode = $currentEpoch.'**Passcode**';
$len = strlen($encode);
$pad = 16 - ($len % 16);
$encode .= str_repeat(chr($pad), $pad);
还要记住 $key
的长度正好是 16 个字符。如果它更短,ruby 会抛出 CipherError,而 php 会用空字节填充 key 。如果更长,Ruby 仅使用前 16 个字符,但 php 会再次填充它,并使用最后 16 个字符。
关于php - 在 PHP 中加密 (mcrypt),在 Ruby 中解密 (OpenSSL::Cipher),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21485437/