使用PHP中的RSA公钥验证JWT签名

在PHP中,我正在尝试使用AWS的RSA公共来验证AWS身份验证令牌(从getOpenIdTokenForDeveloperIdentity返回的JWT) key(我在 https://cognito-identity.amazonaws中从模数/指数生成的) 的.com /。好知/ jwks_uri )。 关键字从适当的页眉/页脚 ----- BEGIN RSA PUBLIC KEY ----- </ code>等开始。我看了几个PHP库,比如 Emarref \ Jwt \ Jwt </ code>,但是我收到错误:错误:0906D06C:PEM例程:PEM_read_bio:无起始行</ code>。 这一切归结为基本的php函数: openssl_verify </ code>。</ p>

我看过php.net / manual for openssl-verify,但我是 仍然不清楚参数细节。 所需的算法是 RS512 </ code>。</ p>

我能够使用node.js验证JWT令牌,没有任何问题(相同的密钥和令牌)。 为此我使用了库: https://github.com/auth0/node-jsonwebtoken </ p>

不确定为什么这在PHP中不起作用。 我可以不使用RSA公钥吗? </ p>

  function verifyKey($ public_key){
$ jwt = new Emarref \ Jwt \ Jwt();

$ algorithm = new Emarref \ Jwt \ Algorithm \ Rs512 ();
$ factory = new Emarref \ Jwt \ Encryption \ Factory();
$ encryption = $ factory-&gt; create($ algorithm);
$ encryption-&gt; setPublicKey($ public_key);
$ context = new Emarref \ Jwt \ Verification \ Context($ encryption);
$ token = $ jwt-&gt; deserialize($ authToken);

尝试{
$ jwt-&gt; verify($ token, $ context);
} catch(Emarref \ Jwt \ Exception \ VerificationException $ e){
debug($ e-&gt; getMessage());
}
}
</ code> </ pre>

</ div>

展开原文

原文

In PHP, I'm trying to validate an AWS auth token (JWT returned from getOpenIdTokenForDeveloperIdentity) using the AWS's RSA public key (which I generated from modulus/exponent at https://cognito-identity.amazonaws.com/.well-known/jwks_uri). The key begins with the appropriate headers/footers -----BEGIN RSA PUBLIC KEY----- etc. I've looked at a few PHP libraries like Emarref\Jwt\Jwt, however I get the error: error:0906D06C:PEM routines:PEM_read_bio:no start line. It all boils down to the basic php function: openssl_verify.

I've looked at the php.net/manual for openssl-verify, but I'm still not clear on the parameter details. The algorithm needed is RS512.

I am able to verify the JWT token using node.js with no problems (same key and token). For that I used the library: https://github.com/auth0/node-jsonwebtoken

Not sure why this doesn't work in PHP. Can I not use an RSA Public Key?

function verifyKey($public_key) {
  $jwt = new Emarref\Jwt\Jwt();

  $algorithm = new Emarref\Jwt\Algorithm\Rs512();
  $factory = new Emarref\Jwt\Encryption\Factory();
  $encryption = $factory->create($algorithm);
  $encryption->setPublicKey($public_key);
  $context = new Emarref\Jwt\Verification\Context($encryption);
  $token = $jwt->deserialize($authToken);

  try {
    $jwt->verify($token, $context);
  } catch (Emarref\Jwt\Exception\VerificationException $e) {
    debug($e->getMessage());
  }
}

2个回答



您可以尝试使用其他PHP库: https://github.com/Spomky-Labs/jose </ p>

  //文件test.php 
require_once __DIR __。'/ vendor / autoload.php';

use Jose \ Checker \ ExpirationChecker;
use Jose \ Checker \ IssuedAtChecker;
use Jose \ Checker \ NotBeforeChecker;
use Jose \ Factory \ KeyFactory;
use Jose \ Factory \ LoaderFactory;
use Jose \ Factory \ VerifierFactory;
use Jose \ Object \ JWKSet;
use Jose \ Object \ JWSInterface;

//我们创建一个JWT加载器。
$ loader = LoaderFactory :: createLoader();

/ n / /我们加载输入
$ jwt = $ loader-&gt; load($ input);

if(!$ jws instanceof JWSInterface){
die('not a JWS');
}
\ n //请注意,此时签名和声明未经验证

//要验证JWS,我们需要一个包含公钥的JWKSet(在您的情况下来自RSA密钥)。
//我们 使用RSA公钥创建我们的密钥对象(JWK)
$ jwk = KeyFactory :: createFromPEM( '----- BEGIN RSA PUBLIC KEY -----...');

//然后我们在键集中设置这个键(JWKSet对象)
//小心,JWKSet对象是 不可改变的。 当你添加一个键时,你得到一个新的JWKSet对象。
$ jwkset = new JWKSet();
$ jwkset = $ jwkset-&gt; addKey($ jwk);

//我们创建我们的 验证者对象,带有授权签名算法列表(在本例中仅为“RS512”)
//我们添加了一些检查器。 这些检查器将验证声明或标题。
$ verifier = VerifierFactory :: createVerifier(
['RS512'],
[
新的IssuedAtChecker(),
新的NotBeforeChecker(),
新的ExpirationChecker(),

]
);

$ is_valid = $ verifier-&gt; verify($ jws,$ jwkset);

//变量$ is_valid包含一个布尔值,表示签名是否有效。

//如果未验证声明(例如JWT已过期),则抛出异常。

//现在您可以使用$ jws对象来检索所有声明或标题键/值对
</ 代码> </ pre>
</ div>

展开原文

原文

Could you try using another PHP library: https://github.com/Spomky-Labs/jose

// File test.php
require_once __DIR__.'/vendor/autoload.php';

use Jose\Checker\ExpirationChecker;
use Jose\Checker\IssuedAtChecker;
use Jose\Checker\NotBeforeChecker;
use Jose\Factory\KeyFactory;
use Jose\Factory\LoaderFactory;
use Jose\Factory\VerifierFactory;
use Jose\Object\JWKSet;
use Jose\Object\JWSInterface;

// We create a JWT loader.
$loader = LoaderFactory::createLoader();

// We load the input
$jwt = $loader->load($input);

if (!$jws instanceof JWSInterface) {
    die('Not a JWS');
}

// Please note that at this moment the signature and the claims are not verified

// To verify a JWS, we need a JWKSet that contains public keys (from RSA key in your case).
// We create our key object (JWK) using a RSA public key
$jwk = KeyFactory::createFromPEM('-----BEGIN RSA PUBLIC KEY-----...');

// Then we set this key in a keyset (JWKSet object)
// Be careful, the JWKSet object is immutable. When you add a key, you get a new JWKSet object.
$jwkset = new JWKSet();
$jwkset = $jwkset->addKey($jwk);


// We create our verifier object with a list of authorized signature algorithms (only 'RS512' in this example)
// We add some checkers. These checkers will verify claims or headers.
$verifier = VerifierFactory::createVerifier(
    ['RS512'],
    [
        new IssuedAtChecker(),
        new NotBeforeChecker(),
        new ExpirationChecker(),
    ]
);

$is_valid = $verifier->verify($jws, $jwkset);

// The variable $is_valid contains a boolean that indicates the signature is valid or not.
// If a claim is not verified (e.g. the JWT expired), an exception is thrown.

//Now you can use the $jws object to retreive all claims or header key/value pairs



我能够让这个库工作。 但是我必须使用KeyFactory :: createFromValues而不是KeyFactory :: createFromPEM来构建密钥。 谢谢! </ p>
</ div>

展开原文

原文

I was able to get this library to work. However I had to build the key using KeyFactory::createFromValues instead of KeyFactory::createFromPEM. THANK YOU!

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问