【问题标题】:What is the right public key to verify a gtoken JWT from Google Identity Toolkit?从 Google Identity Toolkit 验证 gtoken JWT 的正确公钥是什么?
【发布时间】:2015-07-30 02:36:19
【问题描述】:

我正在尝试验证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 模块,但遇到了同样的问题,即密钥比签名短。

【问题讨论】:

  • 总是 use strictuse warnings,尤其是在寻求代码帮助之前。您私下做什么取决于您,但请至少在此处写问题之前表现出已做出努力。
  • 嗯,我从一个较长的脚本中剪切和粘贴。我总是使用严格并使用警告。我已经尝试以十几种不同的方式(包括不同的语言)来实现这个东西十几次。这里的问题不在于语言,而在于 256 字节签名与 128 字节公钥。代码仅供参考。我也没有包括 #!行或内容类型标题输出或任何数量的其他细节,我认为这些细节会分散我的注意力。但我确实测试了发布的脚本。
  • 我的意思是,无论如何您都不能轻松运行此脚本。您需要设置 Google Identity Toolkit 并为自己获取一个 gtoken cookie 集。这需要做一些事情,所以我不是在寻找代码审查,而是在寻找已经知道验证 Google 签名的 id 令牌 JWT 上的签名所需的加密步骤的人。我通读了谷歌库上几种不同语言的源代码。一切似乎都表明你应该完全按照我上面所做的那样做。所以我想知道我是否使用了错误的加密算法或获取了错误的密钥。

标签: perl x509 sha256 jwt google-identity-toolkit


【解决方案1】:

Google 提供了移植到各种语言的 gitkit 库,并且它(至少对于我使用的 node.js 版本)具有一种从公共 uri 轻松检索公钥的方法。 Perl 似乎不是其中一种语言,因此我建议您获取 Python 版本并尝试以 Perl 的方式模仿它。

在此处查看 API 参考和 gitgit 库从中获取公钥的 uri:https://developers.google.com/identity/toolkit/web/reference/relyingparty/getPublicKeys

在此处查看 Python 快速启动应用程序。它有图书馆的链接:https://developers.google.com/identity/toolkit/web/quickstart/python

祝你好运。

【讨论】:

    猜你喜欢
    • 2017-09-24
    • 2021-08-14
    • 2018-04-10
    • 2019-08-25
    • 2016-04-23
    • 1970-01-01
    • 1970-01-01
    • 2021-08-21
    • 2020-11-16
    相关资源
    最近更新 更多