我编写了一个测试脚本,用于签名,然后使用PS256算法验证JWT。
我的代码成功验证了JWT,但是在jwt.io调试器中验证失败。
我正在使用jws@3.2.1
。
仅在使用PS256算法时会发生这种情况,例如在使用RS256时不会发生这种情况。
我做错什么了吗?
我用以下方法生成了密钥:
openssl genpkey -algorithm RSA -out private_key2.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in private_key2.pem -out public_key2.pem
您可以在repl.it上尝试我的代码:https://repl.it/@SamArtuso/Nodejs-Signature-verification-PS256-succeeds-in-Nodejs
代码:
const { join } = require('path');
const { readFileSync } = require('fs');
const jws = require('jws');
const ALG = 'PS256';
/**********
* SIGNING
**********/
const PRIVATE_KEY_PATH = join(__dirname, './keys/private_key2.pem');
const privateKey = readFileSync(PRIVATE_KEY_PATH).toString();
const payload = {
foo: 'bar',
};
const token = jws.sign({
header: { alg: ALG },
payload,
privateKey,
})
console.log('Token:');
console.log(token);
/************
* VERIFYING
************/
const PUBLIC_KEY_PATH = join(__dirname, './keys/public_key2.pem');
const publicKey = readFileSync(PUBLIC_KEY_PATH).toString();
const result = jws.verify(token, ALG, publicKey);
if (result) {
console.log('Verification successful.');
} else {
console.error('Verification failed.');
}
私钥:
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDPR8CD/9V9fddR
vMk590JtuU4hPT9iPD/mYeWdvUTbkN2iPpg6LDADBntz8I9CzThCkgHmDQhh49Qz
AONiHfyHhKT6HHIBS78wGWfhE9ueFtkv19xisvFJTDO6IllGFMiioj8AkvOJwaY+
5ZKSFG32V0gMaglNSNTOh5KK6DsxgdH2KfMzn6uFwJkvsz1qwPiINu/rqvOQPOIK
JCbNHBOg/SvhPWBSEFDC9AkLm3ajhGAcnSlWi0KgUFz7iHuUR6s4GLdkc40uAooY
ExEWsZyoByT18tXln2hPAvE1Ata2PSbtLHuwvMQt4vzZi80K4BXqOiqvNMo1A1aT
oSQnmOwtAgMBAAECggEAPpHTPEVS5aHCCItrVtMbu1FvkzsQ0g+L3nh4vqfujDTr
olkwzIagK5meVH4uUKTwMbAvYIlYmWwTlx3ShcC1hRb2UgWaKGf8G4HfyKKc7djJ
0NZhUW3gxhZ5mttZhX0qn2VIjVzOpSvOijf0iaIfG3h3aD/t9OViT8G+6610iNmz
Oygmi9kQaBAS2A2sLSSMhdyddIPEpZ8QOHwGCRvBXWO100BCV9ROQzYxW+U9VPaJ
I0tXDL1L1H7y1EbxccPfOsfUPMtF9LQWQZ6ksJuSRwkBAnfKpzexguph29sLDjCQ
X23rQN/NwiU+zRmn+cW7VqkZsbSqucP9t+d19UdWpQKBgQDn9sThxAZvx4OS0noD
AWJX5CliDNlagmLqr4c0QoYI+fPL7FcK9tQYUZ869jnebX7UPHTuDhMoIvWknZbB
QhoogpRoX+XFtxzPwjtBBGc5TYacYnOR4xPSjvDlIrY7FQiH8TgpAGzenSBiD8O0
xW4zSaHLUDHEMFEyPq8tdMmBewKBgQDkwjUnVMPlA9AOD+KQNXgf2kV9z0ZA5idt
9WcsXsxpO2W6S0ntkr29Yr3VuuuJTRH7Fm+bPDJ6C1bfZ746hn3iLMZbMxgGVEf/
cN0nNXjfG5G7EEIU9WFges1I5rec/5W38kIco6soP36Qj5HcUBXt6AHy3k1IbEL2
84Bp1SZ0dwKBgF19mhCcXzPCKAePCVoYvrhJ31wDbb8K+i84m7e2cCtCAr7X/KUQ
op9Clni/MMezPgDwdPhVd+cfX/3+/fnaWIynRIVk0UkE6nnaAOPNkIUJ+A0jqQzN
hvnAXtsbSHM7oPqZgFcWMsrubVTYobpEMIw/SxSUt9oo1zD3Dse1YFntAoGBAIAL
AIuKU7f9gVhNpehINXvGxfzcpxsueEWBBgX87fe9CnzTJYc4CsJV4aIfZTVOEVF0
xnWipTJQ5IhZ3k2N+CpAG6ryl3D7fe1J9E+9C3H+UXzeZc6rZp0FP6Cdm4riOKBk
loLHTcdSevpZkjA6F3w5z9Vsft+Z0YW+2FLkvwiTAoGAdjUYcGTaEhGNtHQszAeY
2VbeVHwgnajKhaZpKMNTVp/AFgeS5k1lSATlT5wQHD3OAhUn+NAEwUOUBBWOpg+i
jML8loplEcVmdHkfGFsrIvzFFIIXQOWy77s/McTCh2jLkLYO8kIOrGy08JBiZnQ/
Ki/HFS/2yaUbG6UdH8FFp2g=
-----END PRIVATE KEY-----
公钥:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz0fAg//VfX3XUbzJOfdC
bblOIT0/Yjw/5mHlnb1E25Ddoj6YOiwwAwZ7c/CPQs04QpIB5g0IYePUMwDjYh38
h4Sk+hxyAUu/MBln4RPbnhbZL9fcYrLxSUwzuiJZRhTIoqI/AJLzicGmPuWSkhRt
9ldIDGoJTUjUzoeSiug7MYHR9inzM5+rhcCZL7M9asD4iDbv66rzkDziCiQmzRwT
oP0r4T1gUhBQwvQJC5t2o4RgHJ0pVotCoFBc+4h7lEerOBi3ZHONLgKKGBMRFrGc
qAck9fLV5Z9oTwLxNQLWtj0m7Sx7sLzELeL82YvNCuAV6joqrzTKNQNWk6EkJ5js
LQIDAQAB
-----END PUBLIC KEY-----
编辑:说明了如何重现我的问题。
npm init -f && npm install jws && node test.js
Verification successful.
以下是我的脚本将生成的令牌的示例。请记住,PS256具有概率而不是确定性签名,因此每次运行脚本时,签名都会有所不同。
eyJhbGciOiJQUzI1NiJ9.eyJmb28iOiJiYXIifQ.Rn6i-94ovuKOVRc2jzLVS40MpMmBkIfkyvF56JK3tM8wvg-DW943NNbXf01bhRdyoUj0A73NSQtz0kB4WfXN1uAH1omzNr0ww-iTfC23AX0OcjbsE7CcDz_ZQWWOzwEGGFVfV9ez5yn1pKRYVdFaKqApk3irP-ej_WGrrJfgeZVs683lNk0WjKOYhj6vsryuz52c0OEJ0UmYy7hSSfL38jgL6bdE0awg2DgiaU6qszZEkMjSnugoMobeAUUyOiXHsR79NryuhCQko-I9P1vKd1dEA3zM1iut5sW5FwB8K9Fi49gaQy0zHk72txJvUWdxW5ns0Svft3qLke5XMuqm2g
答案 0 :(得分:0)
我试图将您的令牌,您的公共密钥和您的私有密钥复制并粘贴到jwt.io的调试器中。这是我的发现:
因此,显然,问题归结为一个问题,为什么只有提供了私钥,才能验证令牌的签名……
这使我想到一个假设,即私钥和公钥在某种程度上不匹配。因此,我尝试从您提供的私钥中重新生成(或更好地提取)公钥,并将其与您建议的公钥进行比较。因此,我将您的私钥粘贴到名为privateKey.pem
的文件中,并运行以下命令:
$ openssl rsa -in privateKey.pem -pubout
这给了我以下公共密钥:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz0fAg//VfX3XUbzJOfdC
bblOIT0/Yjw/5mHlnb1E25Ddoj6YOiwwAwZ7c/CPQs04QpIB5g0IYePUMwDjYh38
h4Sk+hxyAUu/MBln4RPbnhbZL9fcYrLxSUwzuiJZRhTIoqI/AJLzicGmPuWSkhRt
9ldIDGoJTUjUzoeSiug7MYHR9inzM5+rhcCZL7M9asD4iDbv66rzkDziCiQmzRwT
oP0r4T1gUhBQwvQJC5t2o4RgHJ0pVotCoFBc+4h7lEerOBi3ZHONLgKKGBMRFrGc
qAck9fLV5Z9oTwLxNQLWtj0m7Sx7sLzELeL82YvNCuAV6joqrzTKNQNWk6EkJ5js
LQIDAQAB
-----END PUBLIC KEY-----
不幸的是,这也是您提供的公用密钥,因此我们可以从列表中删除此想法。
因此,我开始在网上搜索并通过Auth0找到this blog post,他们在其中描述了对PS*
算法的支持,但是根据文档,一切都会按预期进行。嗯,更奇怪
因此,我接下来要尝试的是使用jwt.io的调试器,使用令牌的解码值,算法PS256
和提供的私钥对事物进行加密。这使我有了这个令牌:
eyJhbGciOiJQUzI1NiJ9.eyJmb28iOiJiYXIifQ.wzkD7q5lH_qJw_V6DJLk72TDqpzA05KN3XHfEFOeAQgCriodoOLrgQ-p3ifIzK525puiV1hnXQuJ-6TEZRqiO8dqlPWQJbG1mLdTTx7ZwdUKsDjY6CMsmsskU8eVrzfaSDVmGvbjaWKq1_KGvtk4vMT0Z9m_YhUjD_SDVbCaZReEbzxta4APM7dMQ5mRFzD03JTwe05_AqayrfXdTungeBEJcMB0tY_4FjWiKbBZOpyQLebzPJ69VgpQFGvf6fPuKT6_3LTEHPrRNFL05OYpgRvayh3pEAF297aSCQ_SFi9slqDdVKkor-q8UDO-zM7J952uCkr7NkXV0Loq62_gMg
如果将 this 令牌粘贴到jwt.io的调试器中,并使用 your 公钥,则签名有效。因此,基本上PS256
似乎可以与jwt.io一起使用,但是出于某种原因而不是您的令牌…
这最终使我想到也许Node.js和jwt.io确实使用不同的方式来运行PS256
算法。当然,由于这是一个标准,因此两者应该以相同的方式工作,但显然它们并非如此。我不知道这两者都是谁做错了,或者我俩都以不同的方式工作是否还好,因为我以前从未处理过PS256
。
很抱歉,我在这里没有更好的答案,但是我想找出真正原因的唯一方法是调试到Node.js的加密代码,并看看jwt.io的源代码(据我所知,这是不公开的)。
从我的角度来看,您所做的是正确的,我想这是Node.js或jwt.io或两者中的错误
PS:写完这个答案后,我发现this issue,我猜原来的作者是你(不是吗?),那里的回答基本上得出相同的结论,那就是问题所在网站。所以也许这实际上是您可以获得的最佳答案。
答案 1 :(得分:-2)
确保正确复制密钥。
https://jwt.io/要求您复制包含END
和> ind_sum<-read.csv("Washington_ind.csv",header=FALSE,sep=",")
> ind_sum
V1
1 229.6161795
2 93.56251442
3 733.6790106
4 0.579372878
5 202.5939352
标签行的行
----- BEGIN公钥-----
----- END公钥-----