是否可以在 Php 中加密 JWT 令牌并在 Javascript 中解密?

Posted

技术标签:

【中文标题】是否可以在 Php 中加密 JWT 令牌并在 Javascript 中解密?【英文标题】:Is it Possible to Encrypt a JWT token in Php And Decrypt in Javascript? 【发布时间】:2017-03-07 00:52:09 【问题描述】:

我目前正在为 JWT 使用两个库。第一个用于服务器端

jose php Library

第二个用于客户端

jose js library

我正在创建一个基于令牌的登录系统。我想要的只是在服务器端创建一个令牌,并在使用 JWE(JSON WEB ENCRYPTION) 加密后将该令牌返回给客户端并保存到 html5 本地存储。

问题是在 javascript JOSE 库中解密加密令牌

【问题讨论】:

【参考方案1】:

因为JWE是一种标准格式,所以从一个平台(PHP、Java、JS...)发出JWE并用另一个平台读取它是没有问题的。

这里唯一的问题是

您必须为要使用的每个平台找到一个库。 这些库必须有通用算法

我不知道nov/jose-php,但代码审查和我执行​​的测试表明它支持一些众所周知的算法(RSA1_5/RSA-OAEP/dir 用于密钥加密和A128CBC-HS256/@987654331 @ 用于内容加密)。

如果您在项目中使用RSA-OAEPA128CBC-HS256A256CBC-HS512,那么您应该能够在一侧加密并在另一侧解密。

如果您想在 PHP 上使用其他算法,例如 AxxxKWAxxxGCM,您应该查看支持十几种算法、压缩等的 spomky-labs/jose PHP 库。

您还应该查看jwt.io,其中列出了多个平台上的大量 Jose 实现。

编辑

私有/公共 RSA 密钥转换器

spomky-labs/jose:

<?php
use Jose\Factory\JWKFactory;
$key = JWKFactory::createFromKeyFile('/path/to/your/key.pem');
// The variable $key is a JWKInterface instance that can be easily converted into a JSON object: json_encode($key)

在纯 PHP 中:

<?php
$res = openssl_pkey_get_private($data);
if (false === $res) 
    $res = openssl_pkey_get_public($data);

// Verify here that $res is not false.


$details = openssl_pkey_get_details($res);
//Verify here that the array $details has a key 'rsa' (could be 'ec')

$components = [
    'n'  => 'n',
    'e'  => 'e',
    'd'  => 'd',
    'p'  => 'p',
    'q'  => 'q',
    'dp' => 'dmp1',
    'dq' => 'dmq1',
    'qi' => 'iqmp',
];

$key = ['kty' => 'RSA'];
foreach ($details['rsa'] as $key => $value) 
    if (in_array($key, $components)) 
        $key[array_search($key, $components)] = Base64Url::encode($value); // Base64 Url Safe encoding. See https://github.com/Spomky-Labs/base64url
    

// The variable $key is an array with the expected information

【讨论】:

jose php 库使用公钥加密,私钥解密 PEM 格式,javascript 库使用 json 格式的 RSA 密钥。那么告诉我如何将 PEM 格式的公钥或私钥转换为 JSON 格式的 RSA 密钥 我刚刚更新了我的答案。希望对你有帮助。 我在 javascript 中需要同样的东西 PHP JOSE 库自 2018 年底以来未得到积极支持。其安全支持将于 2020 年终止。库页面建议使用PHP JWT Framework。

以上是关于是否可以在 Php 中加密 JWT 令牌并在 Javascript 中解密?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Thinktecture Identity Server 中加密 JWT 令牌?

是否可以从服务器(Java)验证 Firebase 令牌(JWT)

加密 JWT 有效负载

加密 Nodejs JWT 令牌

HMAC 256 与 HMAC 512 JWT 签名加密

带有 PHP 和 Angular.js 的 JWT(JSON Web 令牌)