donglieshe4692 2016-01-12 21:48
浏览 574

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

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条回答 默认 最新

  • dqh1992 2016-01-13 20:38
    关注

    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
    
    评论

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题