我能够用旧版本的荷西解密JWE,但我很难使用最新版本的API。
我的令牌标头如下:
{
"alg": "A128KW",
"enc": "A128CBC-HS256",
"typ": "JWT"
}使用jose 2.0.3,此代码(从另一个堆叠溢流柱复制)正在对有效负载进行解密:
const { JWK, JWE } = require('jose');
const privateKey = JWK.asKey("my key");
const jwe = "my JWE"
const jwt = JWE.decrypt(jwe, privateKey);
const payload = Buffer.from(jwt.toString().split('.')[1], 'base64');
const data = JSON.parse(payload);显然我不能分享私钥。这是一个有16个字符的字符串。
我试图使用jose的更高版本(4.9.2),但是API完全改变了。我试过了,但结果并不好:
const jose = require('jose');
const jwe = "my token";
const key = await jose.importJWK({ kty: 'oct', k: 'my key', alg: 'A128CBC-HS256' })
const { plaintext, protectedHeader } = await jose.compactDecrypt(jwe, key);
console.log(protectedHeader)
console.log(new TextDecoder().decode(plaintext))我知道这个错误:
TypeError: Invalid key size for alg: A128KW我确认我的键长为16个字符(通常为128位),所以我不会收到这个错误。有什么暗示吗?
发布于 2022-10-06 07:39:18
问题是你的秘密钥匙。您正在使用16个字符串并将其作为JWK传入。JWK k是base64url编码的,所以当“解码”时,您的16个字符“编码”就变成了一个12字节的秘密。
下面是要工作的内容,不要为对称机密进行密钥导入,只需传递一个缓冲区实例即可。
const { plaintext, protectedHeader } = await jose.compactDecrypt(jwe, Buffer.from('my 16 bytes secret'));
console.log(protectedHeader)
console.log(new TextDecoder().decode(plaintext))此外,如果您的有效负载是JWT声明集,那么还不如结合解密操作进行正确的JWT验证。文档
const { plaintext, protectedHeader } = await jose.jwtDecrypt(jwe, Buffer.from('my 16 bytes secret'));
console.log(protectedHeader);
console.log(payload);发布于 2022-10-05 19:21:01
这是关于jwt和jwe的完整示例。全工程,生成,验证,如何使用
产生jwt和jwe
let jwt = require('jsonwebtoken'),
{
JWK,
parse
} = require('node-jose');
async function getJwtEncrypt(raw, format = 'compact', contentAlg = 'A256GCM', alg = 'RSA-OAEP') {
let publicKey = await JWK.asKey(process.env.JWT_PUBLIC_KEY, 'pem');
const buffer = Buffer.from(JSON.stringify(raw));
return await JWE.createEncrypt(
{format: format, contentAlg: contentAlg, fields: {alg: alg}}, publicKey)
.update(buffer).final();
}
function getJwtSign(payload, subject) {
const SIGN_OPTIONS = {
subject: `${subject}`,
expiresIn: payload.expiresIn,
algorithm: 'RS256'
};
return jwt.sign(payload, process.env.PRAIVATE_KEY, SIGN_OPTIONS);
}验证jwt和jwe
let jwt ,
{
TokenExpiredError,
JsonWebTokenError
} = require('jsonwebtoken'),
{
JWK,
parse
} = require('node-jose');
function getJwtVerify(token, cb) {
try {
jwt.verify(token, process.env.PUBLIC_KEY, {}, (err, decoded) => {
if (err !== null && err instanceof TokenExpiredError) {
cb('TOKEN_EXP');
return Json.builder(Response.HTTP_UNAUTHORIZED_TOKEN_EXP);
}
if (err instanceof JsonWebTokenError) {
cb('IN_VALID_TOKEN');
return Json.builder(Response.HTTP_UNAUTHORIZED_INVALID_TOKEN);
}
cb(decoded);
});
} catch (e) {
ValidationException(e);
}
}
async function getJwtDecrypt(encryptedBody) {
try {
let keystore = JWK.createKeyStore();
await keystore.add(await JWK.asKey(process.env.JWE_PRAIVATE_KEY, 'pem'));
let outPut = parse.compact(encryptedBody);
let decryptedVal = await outPut.perform(keystore);
let token = Buffer.from(decryptedVal.plaintext).toString();
if (typeof decryptedVal.plaintext === ('undefined' || null))
return Json.builder(Response.HTTP_UNAUTHORIZED_INVALID_TOKEN);
return token.replace(/["]+/g, '');
} catch (e) {
ValidationException(e);
}
}.env文件
PRAIVATE_KEY = "-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDHRyVyzQTw5XkTaM3bgfKE5Ry+CqqmijpvHprM1Dvkr3q7lR2A
ZTzKGnyHVbnVpKPga8AHs3E7l/MVci2BhWLbHGOn4GgrrqDmItvCvFcfGZM9USZE
2tp5zLj3aBoqImk+niFHQipSPus9JhNU9HkLNTUJGwuuxfWuXwtnMhWcpwIDAQAB
AoGAMs9bJwhLSDjaRC6mvl9FvMjGKVaC6G+6Mnb1NWCv3ME5Y/bDTOeDNmzGb6NV
/Lk7547RqaUBLBa0LjWskKe36n6hfWExEaRe9ikqRiz6y0QXyfO5h6qZD0YXSsIu
5VY8LBCz45Z330I296jLbgkZ2OhZbEj8lk8rf99JtzGzRBECQQD1W0cBRIKt6e8g
KJNLp8A0dLId6bbmgG5xnOscTMfxzZAvMAz6eN4ur8vkJKDVr1YjRCHETrfdaX/d
kfY/29TtAkEAz+wokyzPERFA+XCdLLW9d9b3nPQhTUodBIq9EXfnhPAXRWzjObLl
zItS3bDzWpGqfwP7nc9zjpcqY0zKdJ+5YwJASnyDeecKpTG33tNypC0xNLuYt2wU
krW60dMJrXXB3a7CbxDvX7sB+Lp187UK/tRUGjC875PWTemRX/rH/2sFoQJBAIN8
MFyB5aBBbPlRAdQYSezTAFs89yJNT/RjWBUH4lzrB4xbw4XlX/Tt1kVjdUE9BLi1
6BRv7/+oEKIjGZSOvUkCQEdb/CPaqXPfn7zA/SKL3hgJbbEo8aowOM4VfV+ZVojp
vzvj/ZjQpRKDEJ7iiJCXBUT59BwPuirq8v6fjWMRneU=
-----END RSA PRIVATE KEY-----"
PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHRyVyzQTw5XkTaM3bgfKE5Ry+
CqqmijpvHprM1Dvkr3q7lR2AZTzKGnyHVbnVpKPga8AHs3E7l/MVci2BhWLbHGOn
4GgrrqDmItvCvFcfGZM9USZE2tp5zLj3aBoqImk+niFHQipSPus9JhNU9HkLNTUJ
GwuuxfWuXwtnMhWcpwIDAQAB
-----END PUBLIC KEY-----"
JWE_PRAIVATE_KEY = "-----BEGIN RSA PRIVATE KEY-----
MIICWgIBAAKBgFsiRgcjHE4S0uoNvOEz/YdmPRRBo+APWpWpM8+B2JSXNZdQCoin
7psz8Pup+4C95Qz/R5Zhw/IZBfvOpD6Hj9v9cMgnnMjPYW6eecByJ6S6lynetRLT
Igy4ICRynhx4rHvRwXpr6dEeaazArDJlwutMv9cW7DdSPiqRSTl9YAffAgMBAAEC
gYAsZ1qvh4/3CnzxxZfOMsLJAiuofwMV3OVKHpM7/AxG+hYGj91SEGDWBkzYkk4U
wHGmD4wV3bTXdRHRSzIDtZGGDZbneWN58TRUPuSP1XiNVIb8Doaj91cprRiBxlmM
ZHJsix/OLN/Sm3UjuZolSjG3K0QucrrBUtPBfhxJ5GXmYQJBAKOwYZHyhz9gGrW7
zkkF9Fivu9P/H0/eS4HaTQLYEUG475KIj6xQLrjTRtxZ139DV3jrGoLEapFvAaOk
fETiBwMCQQCOhy7Aa5muKcELFJqxzY1CWLCaayX43ZPVYKCkLaqDYRWtufLjZ3vj
hWiQScULEGLiM+axZFgTmbtWI6oy4cb1AkBT+UeEzQvvSklJlChWs/RPjw/nyQjy
O1M3MZuyatAnjE1zOhWiy5u8e77tijWQdyanxMzb6xHUvEL2BYsu91mrAkAbq/tT
uJBZ1Bl6wUFXjAUFAJspH+x7aOmu39fQiF02rL68wAF8TTcscVZfzTLIdyH7sP/1
KPpAs/Q/QSVmQ5eRAkBHWQgmTC5MsmLmJO6UdUjOp5a9rJzxnMej8zUiR/lZ7ssc
4jAfqi8ukBv+5THumh3TKDNPAu9+r5nWOahb/jrJ
-----END RSA PRIVATE KEY-----"
JWT_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----
MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgFsiRgcjHE4S0uoNvOEz/YdmPRRB
o+APWpWpM8+B2JSXNZdQCoin7psz8Pup+4C95Qz/R5Zhw/IZBfvOpD6Hj9v9cMgn
nMjPYW6eecByJ6S6lynetRLTIgy4ICRynhx4rHvRwXpr6dEeaazArDJlwutMv9cW
7DdSPiqRSTl9YAffAgMBAAE=
-----END PUBLIC KEY-----"https://stackoverflow.com/questions/73964715
复制相似问题