如何使用PHP生成Google ReCaptcha V2安全令牌?

ali*_*gex 9 php security encryption token recaptcha

我正在尝试为ReCaptcha V2生成安全令牌,如下所述:https: //developers.google.com/recaptcha/docs/secure_token

不幸的是,我生成的stoken无效,我无法找到一种方法来检查它为什么不起作用.有一个工作的Java示例(STokenUtils.java),但我发现自己无法将其转换为PHP.

public static function generateSecurityToken($secretKey){
    $stoken = array(
        'session_id' => session_id(),
        'ts_ms' => round(microtime(true)*1000)
    );
    $secretKey = self::pkcs5_pad(hash('sha1', $secretKey), 16);
    $stoken_json = json_encode($stoken);
    $stoken_crypt = self::encrypt(self::pkcs5_pad($stoken_json, 16), $secretKey);
    return $stoken_crypt;
}

public static function encrypt($sStr, $sKey) {
    return base64_encode(
        mcrypt_encrypt(
            MCRYPT_RIJNDAEL_128, 
            base64_decode($sKey),
            $sStr,
            MCRYPT_MODE_ECB
        )
    );
}

public static function pkcs5_pad ($text, $blocksize) { 
    $pad = $blocksize - (strlen($text) % $blocksize); 
    return $text . str_repeat(chr($pad), $pad); 
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以提供一个有效的PHP示例或指出我的代码中的任何明显错误吗?

slu*_*hie 10

您的代码中存在许多问题.首先,$secretKey当实现需要SHA1哈希的前16个字节时,您的值被计算为填充SHA1哈希.

$secretKey = substr(hash('sha1', $secretKey, true), 0, 16);
Run Code Online (Sandbox Code Playgroud)

其次,您正在尝试执行密钥的base64解码,这在此处无效.第二个论点mcrypt_encrypt()应该是$sKey,而不是base64_decode($sKey).

最后,正如x77686d的答案中所解释的那样,您应该使用"URL安全"base64.这是base64的一个变种,它是未填充的,不使用+/字符.相反,-_字符用在他们的位置.

诚实地说,ReCaptcha的安全令牌有点痛苦.它们不安全,算法没有记录.我和你一样处于同样的位置,需要一个实现,所以我写了一个并在Packagist上发布它作为"slushie/recaptcha-secure-token".我建议使用它和/或贡献,如果只是因为缺乏该算法的替代实现.