在 PHP 中生成 Paseto V2 Public Key/Token,在 Node.js 中验证
Generate a Paseto V2 Public Key/Token in PHP, Verify in Node.js
前言:
什么是 Paseto?:https://developer.okta.com/blog/2019/10/17/a-thorough-introduction-to-paseto
我已经能够使用 PHP 库成功创建 Paseto V1 令牌和相应的 public 密钥(密钥对在服务器端使用 RSA 私钥),并且然后使用 public 密钥验证 Node.js 端的给定令牌:
PHP 帕塞托 Public V1:
$privateKeyV1 = new AsymmetricSecretKey($rsaPrivate, new Version1());
$publicKeyV1 = $privateKeyV1->getPublicKey();
$token = (string) (new Builder())
->setKey($privateKeyV1)
->setVersion(new Version1())
->setPurpose(Purpose::public())
// Set it to expire in one day
->setExpiration(
(new DateTime())->add(new DateInterval('P01D'))
)
->setAudience('Foo')
->setIssuedAt(new DateTime())
->setIssuer('Bar')
->setNotBefore()
->setSubject('IDP Paseto')
->setClaims([
'claim' => json_decode($this->claimJSON(), true),
])->toString();
return $response->withJson([
'public_key_v1' => $publicKeyV1->raw(),
'token' => $token
]);
NodeJS Paseto Public V1:
const token = "v1.public.sdsw5vsdf4554...............exampletoken:"; // Example paseto V1 token
const pubKey = await createPublicKey("-----BEGIN PUBLIC KEY-----\r\npubKeyFromAbovePHP\r\n-----END PUBLIC KEY-----"); // Example public key
const response = await verify(token, pubKey);
效果很好,我可以在 Node.js 中验证我的声明并使用摄取的数据处理我需要的内容。
现在,如果我尝试以下 w/V2,在 public 键上调用 bin2hex()
以便能够存储它并在 Node.js 端使用它,我无法在 Node.js 中正确验证。我相信它与钠加密二进制密钥生成有关,以及 $publicKey->encode()
如何使用 Base64UrlSafe::encodeUnpadded($this->key);
但我不确定..我从来没有从 public使用 V2 创建的密钥,我相信它只是存储为二进制文件?
PHP 帕塞托 Public V2:
$privateKeyV2 = AsymmetricSecretKey::generate(new Version2());
$publicKeyV2 = $privateKeyV2->getPublicKey();
$token = (string) (new Builder())
->setKey($privateKeyV2)
->setVersion(new Version2())
->setPurpose(Purpose::public())
->setExpiration((new DateTime())->add(new DateInterval('P01D')))
->setClaims([
'claim' => json_decode($this->claimJSON(), true),
])->toString();
return $response->withJson([
'public_key_v2' => bin2hex($publicKeyV2->raw()),
'token' => $token
]);
NodeJS Paseto Public V2:
const pubKey = await createPublicKey(Buffer.from('public_key_from_php_response_above', 'hex'));
const token = 'token_output_from_php_response_above';
const response = await verify(token, pubKey);
console.log(response);
感谢您提供的任何反馈。如果您有任何其他问题,请告诉我。我为 PHP 框架用 slim
标记了它,因为我在一个 slim 项目中使用 PHP paseto lib 将 public/private 键存储在我的 slim 容器上,等等。和 NodeJS 在 lambda 的上下文中。
如果有人仍然需要答案 - 使用
V2.bytesToKeyObject(publicKey)
对我有用。
因此,不要使用加密库的 createPublicKey
方法,而是使用 paseto V2 的 bytesToKeyObject
方法来生成密钥以输入 V2.verify.
const { V2 } = require('paseto');
const publicKeyString = Buffer.from('Wxar8cbJRI9flcB', 'base64'); // or 'hex' if that's the encoding you used initially
const pubKey = V2.bytesToKeyObject(publicKeyString);
const payload = await V2.verify(token, publicKey);
就我而言,我使用的是 public paseto 方案,其中签名者是 Rails 应用程序上的 Ruby,验证者是下游节点应用程序。
在 Ruby 中,我使用 mguymon 的 paseto gem https://github.com/mguymon/paseto.rb (v2)
创建了 public/private 密钥对
前言:
什么是 Paseto?:https://developer.okta.com/blog/2019/10/17/a-thorough-introduction-to-paseto
我已经能够使用 PHP 库成功创建 Paseto V1 令牌和相应的 public 密钥(密钥对在服务器端使用 RSA 私钥),并且然后使用 public 密钥验证 Node.js 端的给定令牌:
PHP 帕塞托 Public V1:
$privateKeyV1 = new AsymmetricSecretKey($rsaPrivate, new Version1());
$publicKeyV1 = $privateKeyV1->getPublicKey();
$token = (string) (new Builder())
->setKey($privateKeyV1)
->setVersion(new Version1())
->setPurpose(Purpose::public())
// Set it to expire in one day
->setExpiration(
(new DateTime())->add(new DateInterval('P01D'))
)
->setAudience('Foo')
->setIssuedAt(new DateTime())
->setIssuer('Bar')
->setNotBefore()
->setSubject('IDP Paseto')
->setClaims([
'claim' => json_decode($this->claimJSON(), true),
])->toString();
return $response->withJson([
'public_key_v1' => $publicKeyV1->raw(),
'token' => $token
]);
NodeJS Paseto Public V1:
const token = "v1.public.sdsw5vsdf4554...............exampletoken:"; // Example paseto V1 token
const pubKey = await createPublicKey("-----BEGIN PUBLIC KEY-----\r\npubKeyFromAbovePHP\r\n-----END PUBLIC KEY-----"); // Example public key
const response = await verify(token, pubKey);
效果很好,我可以在 Node.js 中验证我的声明并使用摄取的数据处理我需要的内容。
现在,如果我尝试以下 w/V2,在 public 键上调用 bin2hex()
以便能够存储它并在 Node.js 端使用它,我无法在 Node.js 中正确验证。我相信它与钠加密二进制密钥生成有关,以及 $publicKey->encode()
如何使用 Base64UrlSafe::encodeUnpadded($this->key);
但我不确定..我从来没有从 public使用 V2 创建的密钥,我相信它只是存储为二进制文件?
PHP 帕塞托 Public V2:
$privateKeyV2 = AsymmetricSecretKey::generate(new Version2());
$publicKeyV2 = $privateKeyV2->getPublicKey();
$token = (string) (new Builder())
->setKey($privateKeyV2)
->setVersion(new Version2())
->setPurpose(Purpose::public())
->setExpiration((new DateTime())->add(new DateInterval('P01D')))
->setClaims([
'claim' => json_decode($this->claimJSON(), true),
])->toString();
return $response->withJson([
'public_key_v2' => bin2hex($publicKeyV2->raw()),
'token' => $token
]);
NodeJS Paseto Public V2:
const pubKey = await createPublicKey(Buffer.from('public_key_from_php_response_above', 'hex'));
const token = 'token_output_from_php_response_above';
const response = await verify(token, pubKey);
console.log(response);
感谢您提供的任何反馈。如果您有任何其他问题,请告诉我。我为 PHP 框架用 slim
标记了它,因为我在一个 slim 项目中使用 PHP paseto lib 将 public/private 键存储在我的 slim 容器上,等等。和 NodeJS 在 lambda 的上下文中。
如果有人仍然需要答案 - 使用
V2.bytesToKeyObject(publicKey)
对我有用。
因此,不要使用加密库的 createPublicKey
方法,而是使用 paseto V2 的 bytesToKeyObject
方法来生成密钥以输入 V2.verify.
const { V2 } = require('paseto');
const publicKeyString = Buffer.from('Wxar8cbJRI9flcB', 'base64'); // or 'hex' if that's the encoding you used initially
const pubKey = V2.bytesToKeyObject(publicKeyString);
const payload = await V2.verify(token, publicKey);
就我而言,我使用的是 public paseto 方案,其中签名者是 Rails 应用程序上的 Ruby,验证者是下游节点应用程序。
在 Ruby 中,我使用 mguymon 的 paseto gem https://github.com/mguymon/paseto.rb (v2)
创建了 public/private 密钥对