J'ai essayé sans succès de déchiffrer la charge utile, un jeton Web JSON qui devrait contenir des informations personnelles en tant que partie des données utilisateur du flux OAuth2. D'après ce que j'ai lu de JWT, il contient trois parties: l'en-tête, la charge utile et la signature - des chaînes codées en base64 séparées par un point.
Le JWT en question est le suivant:
eyJjdHkiOiJKV1QiLCJhbGciOiJSU0EtT0FFUCIsImtpZCI6IkJGTDBzcVpEZEtPdnBEX29YSllPNDhlbEhQaldTWVB1WmZSczBtT3VLMUEiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.GFxv1iIUdktUO9f-pf_eS_J34QnBHJdSJPokE3p5XE1nPCRwIYmf3n4kq4X9T7tOAvOIEs7-BoeFedzjRQnXKetrLY5wWHCALt4C_Y8Ibu--WseiQJnIKzyEvuhZHonRN6GWaMZB724M2NhtHHXY4pLX7RNsXquaMBFG1sFny20zHWEjSGx4jDOfKkH-f9Ty5hRIKvZXmQ36RsJI4oF1i4j1aPZj-BKiyiorm5c5F-IUcukhm2QObf88K3EFS0mbVvPM7yNAure51LWptBLIKBBq7VPMfq0NXLL_bBzMZ1XdFBDt2qkIteoE9ts44esTeVvsvNSRHGqAtl8EO-10wg.jOvZCvp2DULxkMyiybRjXw.CCeHLVU2GjsSrdND6UYxIN9Ny_QKig7CC_E3uDsHsb1mRaDV9gQ432NGYpD0RndPQoepOppcDsI2zT2yoKCYLYKuig6XDcOl3eK4-MooDjZOHn_9ahYlAiauTFRtiJfHU9rTSMU_eLkH-z1eyzoe3fbEqkK6hWxHELzlYByeof0pINcDRsxwcNG0GDAqrcJ3IdQjLwoupVGLZh-wb3WsqpZbV5Abz2LkV3BK_TqVjlEBEtKBXOZohdieIwEo1kUm_MZJpXzF6HIJkasrrN1c3-uVmMMJbRBDfZv0GBZ4OyNv9q5vTKCY90RF3QVmN604L9v2JAalOmhLgRq1q8on_dk35nKuhynSrr9lMy2ieTD5VcpbDODpwGHPBQJnn99dbYZqu3uWKYURR2mmfCq1IDEgtq3aczgmNmU6QKQ8vUgljSQ75cqwS9GaHHPHuJZeMXRa1ifkuywf7z5kgk8Z4z_jKA1fqnlYSmRASponkuHqkVx-P5ZlRqfjvR9qpG2qz3B4a1Cjmnp2Di8_5jTg09CLYKBMfa42Fgw5lnlivEcGvWIWWd4a0FvYQlDCjDkRfv21DFkleJ23CyJ7Zjsm2CTPZXk9y6G3HzOYgFxyriIw_52VpnzIrgmYsmpm5amBKGbYYeZbthPwVnf1W76yqBziYljAoIP7g1uM0HdjvkqeDTe3Q5_WQAdrmIz8Yjh2z0edjc0ynPPqKLMfEs8SQWMYsodgQ6KcVMGWalYPCV6eF79Ldf5gpah_oXTMP0nn7rKccoiftlNFsgem2p81yTN7AwWKm_fO70EFdpQ1-kez7lQ5OtamdZWR-W3sEtn3K0wdeLbMYtD4bD8RdwKoZ_DZgBLdJenmXAa7P5dkOzxaeUAKTAaYOSq_EKxIH8AtnqyTTXEfRXLxyoFGJlN_N6bSUWytbJr4c1ktxBG4RKWWJpusVA2hiZ2GCFs7PfWRPC7hSFd8V52O1hwuZsAz6BN4pJv1rIicVSJNozMgyv9ZqY5HkOTIUUztsu_Urkre1ItfVcAg1Ia5Fj-OZ7ymm7sNA9JKBV14T4EPtfAcnoLLRr95ngTzsBPu7KKb-EO7k7m1na_sisQaQxlQNJset5_Hi_Oj2Sj1g7tB7Uld64MlQbvOBxBIw_D9hmmjm_v1cbDcLV2XmmXQotLout197vcJahNQOvSb7W9BqXFvxVlSHa89_H75acO4IMYem3lRJXT2ZdwsQhvFZ8BRSN7h-kKl6Z_v3aRNTrbwA_qQDYlH67uP84F9FKqejejCgNGtqzbvNs4SYv64Wsq9Uz6xhAeCXBuxn9EQc83cKsNkUnLwREHTlng3CpQHpZje6dAEpKKOIN5XHOcj04BNwAZP0TnCeGUWqZpxPI3vyFupC5vb5Wt26BOC1MWb0Upn08xAxwY5urtkX4cRFMpnXFHnv-ypfr2UY5KP6Nh2tbahEgZ-1bBw3GaEPYAqros31pyY6E51nCQ2j3kdmFxVuW3fTp5CzHpAPuTSi6zX6r8sttUi-bJK81CTey8TMFtr5sqpYtlLHbUpSsi-YfYeNCfOmSMLESMQRDSh7LmBFbGK9zDavuTALTNMNPVWeJUQOeAcScQWFZLEg8-attDjdcpxVEZAJIXb9frYD4aDyE4WE0vsRj-kP3d0txJ1_c-mG-PjW0_IVIo_9bUHteHGZdyMS1y6NNOhoTlq0XXAs0oRcd7RVojwUYpbVGAvWT7_CDPTKvnJDFALbAu2D7KWFw1dCnDrUW5HzxW274Y0wx25ev3BKpVE5tekBujVNVmqNjIh._JyU-CpPzHItUbTb_syKsg
La charge utile provient d'un service qui est utilisé par le gouvernement finlandais, donc je suppose que son format devrait être correct, mais d'abord je suis confus que le JWT contient cinq parties. La première partie concerne les en-têtes:
{"cty":"JWT","alg":"RSA-OAEP","kid":"BFL0sqZDdKOvpD_oXJYO48elHPjWSYPuZfRs0mOuK1A","enc":"A128CBC-HS256"}
La charge utile doit être chiffrée avec cette clé publique / privée:
const jsonKey = {
p: '7C8pWx6iaZDypKgElaJoDGN_OdZh-mAI6jAZkoA9Io5vQrTNzqdFyTF1j_AsU4KMKATvihtKoTAnZnfH1Dk-nCX6GLpiDOeZAXyv-tTGfINl50YhbI-qu4B8h-CPohzOXpBMrOCplQwR60NcW827aNVu1OTBPRboWgtAyqduWGE',
kty: 'RSA',
q: '3Pxz70nzwiNWQwfXQEXA529HoGP6aFBFY2HRnOWF1M7OlN4OnHE-WRlUeyMFA1junBOtUbBhq8hO3X0zPNZVwUrA1IbzoBZUmCTaL4ClZ6dDATfFMrebj8455wCqJNfpkiAXLhA4eh5j1daAWqMyhr9skx5ZslSYbeRM52zmWUc',
d: 'l6a9RMaox9dYchDoOWHZ_IpXLfZZyN2k47fljDluwkIs4wCGjBbvt9nAX2mjsNttWi7mihLcea0PO5wt9dHhzwrB9xbAKlHNh4_IK9YJhdCg47rECtdDhIHqnvTHx4zYWViC6MBorR094pOQy57Hg2kkJhVkeTLeruBmL1QFf7AkoIICJ11FCIwYHJW8bRfWTBbqh8Rnwq2z620ZE16ZsHTp1TfXWWyOXIuMZXAZfdiQq95zR6npkEdGs_es8mwqgXroXmE2UQMEz-r-9DpTXk3_cbXLFbo8PhrpfD8Mxe8hQOdkD5yGqzGz4Xgnl62iCTRZOwdxH3ayH6z9vXDTAQ',
e: 'AQAB',
use: 'enc',
kid: 'BFL0sqZDdKOvpD_oXJYO48elHPjWSYPuZfRs0mOuK1A',
qi: 'XCkgo29q4ha8iwGc9VJq9y2TsAK7WxjcTZlcOoYFkJqzAdxlBvYKBJ4H_2OQvURo5sVhwWQbHrd_nfHVKe8vos9AYz3b0ylQJODse8Xm2w3gaTrwdb4Z5EN2I_2513O60XIeg2WSLMSkvkfaSkJ20OCM7OeZwVyE_N8dTyafy84',
dp: 'dw1y0D6J6aKp3Lvgy7h4sD37JKFe9AEynTGvwjwoFOItTTesQk3pDHiE5RBQl6vHkGikgj4tiUCnq6wXK2_LkpRGE-7ne8_GPYynfE2C28K0PDcKpBlrG2ax3yAf5ryUffBI5h-8-6eA5NEonhH_NOHZIzFIAs4oQzNG7qAlLCE',
alg: 'RS256',
dq: 'WpjVHuD-ojTChLCOOrdeIoOopcTXQDTIfbn4qY4fk-NFJhrzeoeiu_x6ehEdWQX4rNwUTk01faudSYiunN5yQdBXxcmdz5_YBpf1K0xeg2Q7QCCRI_3KNOajLmVDW994zoOBfU0BGm-jFmPeM0p8yGlqJdZnh4jPBR53uNkYhrk',
n: 'y-Fw7PfbnBie2s408nZICscdQ0-spOTeli0LIkFi5QMgGnQ2mQlTXcypm8UdkYu-Up4tzFUmkd-n0gPKES6cP1YGWn9gXC9DP1GmHQVXuGGAxMLkctYK2-CSCckgLtNcmxzdEtwbtwOmWHFdtBUFvwLKnqU0XEv_wdFEakKHwp12foSUoUH7FbzMbLu5BHo4rjuTU2paHQpiHqoG9qNg-jZFXLdjRGWslJKCJGDUBXB3HIlGykr8ghOdsMlpzRn3zQ8WI77bPN58QlGMXVOQcKivsKhoF9mZOHEceAfPLKgucmI-KwJ7w-6DTAuwCI6eo6hlQc_Gz0JxjPJdH3o75w'
}
Actuellement, je ne peux décrypter la charge utile qu'avec cette bibliothèque :
const { Crypto } = require('@peculiar/webcrypto')
const crypto = new Crypto()
// Payload defined above
const parts = payload.split('.')
function ab2str (buf) {
return String.fromCharCode.apply(null, new Uint8Array(buf))
}
const decrypt = async () => {
try {
const k = await crypto.subtle.importKey('jwk', jsonKey, { name: 'RSA-OAEP', hash: 'SHA-1' }, false, ['decrypt'])
const data = await crypto.subtle.decrypt('RSA-OAEP', k, Buffer.from(`${parts[1]}`, 'base64'))
return ab2str(data)
} catch (err) {
console.log(err)
}
}
decrypt()
Le déchiffrement des rendements ñDõ^îó"ìût=©Z]¬úí³ê
qui n'est pas un objet JSON. D'autres parties (ou une combinaison d'entre elles) généreront une erreur de la bibliothèque. Changer quoi que ce soit dans la charge utile ou la clé lèvera des exceptions, donc je suppose que la phase devrait être correcte, mais la sortie ne l'est pas.
Ma question est la suivante: comment puis-je décrypter cette charge utile en utilisant node.js ou est-elle réellement cassée?
Les clés privées PS et JWT utilisent l'environnement de test, elles ne contiennent donc pas de vrais secrets.
En fin de compte, la solution était très simple. J'avais essayé d'utiliser toute la clé JSON pour quelques bibliothèques différentes, mais en utilisant uniquement la version PEM sans noms, je permettais d'utiliser jose , alors que le magasin de clés ne l'a pas trouvée même si les en-têtes JWE décrivaient clairement la clé utilisée pour le chiffrement.
const { JWK, JWE } = require('jose')
const privateKey = JWK.asKey(/* private key here as PEM */)
const jwe = /* encrypted JWE here */
const jwt = JWE.decrypt(jwe, privateKey)
const payload = Buffer.from(jwt.toString().split('.')[1], 'base64')
const data = JSON.parse(payload)
console.log(data)
Cet article est collecté sur Internet, veuillez indiquer la source lors de la réimpression.
En cas d'infraction, veuillez [email protected] Supprimer.
laisse moi dire quelques mots