我正在尝试验证由Google Identity Toolkit返回的 JSON Web 令牌“gtoken”的签名。
但是,“签名”似乎是 256 个字节,但在https://www.googleapis.com/oauth2/v1/certs找到的证书中的公钥只有 128 个字节。因此,我收到错误“签名比密钥长”。
我正在使用这个 Perl 代码:
use JSON;
use CGI;
use LWP::Simple;
use Crypt::OpenSSL::X509;
use Crypt::OpenSSL::RSA;
use MIME::Base64;
my $cgi = CGI->new();
my $json = JSON->new();
my $gtoken = $cgi->cookie('gtoken');
my ($header64, $body64, $signature64) = split(/\./, $gtoken, 3);
my $signed64 = "$header64.$body64";
$signature64 =~ s/\-/+/g;
$signature64 =~ s/\_/\//g;
my $m = length($signature64) % 4;
$signature64.="==" if($m == 2);
$signature64.="=" if($m == 3);
my $signature = decode_base64($signature64);
# Note that length($signature) == 256 here.
my $certs = $json->decode(get("https://www.googleapis.com/oauth2/v1/certs"));
foreach my $cert (values %$certs) {
eval {
my $x509 = Crypt::OpenSSL::X509->new_from_string( $cert );
my $rsa_pub = Crypt::OpenSSL::RSA->new_public_key($x509->pubkey());
# Note that $rsa_pub->size() == 128 here.
$rsa_pub->use_sha256_hash();
$rsa_pub->verify($signed64, $signature);
};
warn $@ if $@;
}
还有其他地方我应该寻找谷歌用来为谷歌身份工具包签署 JWT 的 2048 位(256 字节)密钥吗?或者有没有办法用 128 字节的公钥验证 256 字节的签名?还是我从证书中错误地提取了公钥?签名是 256 字节的事实意味着,据我所知,我用来验证签名的公钥也应该是 256 字节。
我也尝试使用 JSON::WebToken CPAN 模块,但同样的问题是密钥比签名短。