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

How to generate a Google ReCaptcha V2 secure token with Perl?

我正在尝试使用 google 使用 perl 的安全令牌,如 link 中所述 https://developers.google.com/recaptcha/docs/secure_token

但是总是提示安全令牌无效。 我也检查了这个 link 但没有成功

#!/usr/bin/perl

use Data::UUID;
use JSON;
use Time::HiRes qw/gettimeofday/;
use MIME::Base64::URLSafe;
use Digest::SHA1  qw(sha1 sha1_hex sha1_base64);
use Crypt::Rijndael;

use constant PUBLIC_KEY  => '...';
use constant PRIVATE_KEY => '...';

my $public_key = PUBLIC_KEY;

print "Content-type: text/html;charset=UTF-8\n\n";

my $uuid = Data::UUID->new();

my $uuid1 = $uuid->create_str();
my $uuidstr = $uuid->to_string( $uuid );

my $seconds = gettimeofday(); #in scalar context it returns a
my $ms      = int($seconds*1000);

my %hash;

$hash{'session_id'} = $uuidstr;
$hash{'timestamp'} = $ms;

my $json = JSON->new->allow_nonref;
my $json_text = $json->encode(\%hash);
$json_text =~ s/"//g;

my $sha_one = sha1(PRIVATE_KEY);
my $new_secret_key = substr $sha_one, 0, 16;

my $block_size = 16;
my $pad = $block_size - ((length $json_text) % $block_size);
my $append_str = $pad x $pad;

$json_text = $json_text . $append_str;

my $cipher = Crypt::Rijndael->new($new_secret_key, Crypt::Rijndael::MODE_ECB);
my $cipher_text = $cipher->encrypt($json_text);
my $encoded_text = urlsafe_b64encode($cipher_text);

print <<EOT;
<html>
<head>
  <script src='//www.google.com/recaptcha/api.js'></script>
</head>
<body>
  <form>
    <div class="g-recaptcha" data-sitekey="$public_key" data-stoken="$encoded_text"></div>
  </form>
</body>
</html>
EOT

任何人都可以指出我的代码中的任何明显错误或建议一些已经存在的 perl 代码吗?

我从您的代码开始,但最终得到了一些不同的东西。我不是加密专家,所以我不确定为什么我的方法有效而你的方法无效。但这是我得到的 - 它确实有效:

use strict;
use warnings;
use Crypt::ECB;
use UUID::Tiny ':std';
use Digest::SHA1 qw(sha1);
use MIME::Base64::URLSafe;
use Time::HiRes qw(time);
use Math::Round qw(round);

my $uuid = create_uuid_as_string(UUID_V4);
my $t = round(time * 1000);
my $json = '{"session_id":"' . $uuid . '","ts_ms":' . $t . '}';

my $pad = 16 - (length($json) % 16);
$json = $json . chr($pad)x$pad;

my $crypt = Crypt::ECB->new;
$crypt->padding(PADDING_NONE);
$crypt->cipher('Rijndael') || die $crypt->errstring;
$crypt->key(substr(sha1($c->{captcha_secret_key}), 0, 16));
my $enc = urlsafe_b64encode($crypt->encrypt($json));

我基本上将 this php library 转换为粗略的 perl 来让它工作。