解密node.js中使用A128CBC-HS256加密的JWT

解密node.js中使用A128CBC-HS256加密的JWT,node.js,encryption,jwt,Node.js,Encryption,Jwt,我一直试图解密payload,一个JSON web令牌,它应该包含个人信息,作为OAuth2流的用户数据部分,但没有成功。根据我所读到的,它包含三个部分:标题、有效负载和以点分隔的签名base64编码字符串 所讨论的JWT是: eyJjdHkiOiJKV1QiLCJhbGciOiJSU0EtT0FFUCIsImtpZCI6IkJGTDBzcVpEZEtPdnBEX29YSllPNDhlbEhQaldTWVB1WmZSczBtT3VLMUEiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2

我一直试图解密payload,一个JSON web令牌,它应该包含个人信息,作为OAuth2流的用户数据部分,但没有成功。根据我所读到的,它包含三个部分:标题、有效负载和以点分隔的签名base64编码字符串

所讨论的JWT是:

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
有效载荷来自芬兰政府使用的服务,因此我想它的格式应该是正确的,但首先我对JWT包含五个部分感到困惑。第一部分是标题:

{"cty":"JWT","alg":"RSA-OAEP","kid":"BFL0sqZDdKOvpD_oXJYO48elHPjWSYPuZfRs0mOuK1A","enc":"A128CBC-HS256"}
应使用此公钥/私钥对有效负载进行加密:

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'
}
目前,我只能通过以下方式解密有效负载:

解密产生的不是JSON对象的ñDõ^238;ó236āt=©Z]、úíaú。其他部分或它们的组合将从库中抛出错误。更改有效负载或密钥中的任何内容都会引发异常,因此我猜该阶段应该是正确的,但输出不是

我的问题是:如何使用node.js解密此有效负载,或者它实际上已损坏


p.S.私钥和JWT正在使用测试环境,因此它们不包含任何真正的秘密。

可以通过在点上拆分它们来找到组件,组件采用Base64 URL编码

标头位于开始或组件0处,它表明这是混合加密,AES-CBC和HMAC用于经过身份验证的加密

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)
您对组件1的RSA-OAEP解密成功。如果密文和密钥不匹配,OAEP将出错。但是,它不返回纯文本,而是按顺序返回一个16字节的HMAC密钥和一个16字节的AES密钥!。键值以十六进制表示:

19D7657D5CDBF41E48EB4FF35A970406 DC803B73BD16AEC1B2DF85FCBBD106F3 请注意,密钥取决于标头中设置的经过身份验证的加密算法。您可能希望首先测试该报头,以查看是否使用了可接受的算法,而不是相反的方法,因为这将启用对该算法的降级攻击,永远不要依赖安全参数的输入

顺便说一下,OAEP解密在内部使用MGF1和SHA-1,这是默认值;不要担心其中的SHA-1,散列对OAEP的安全性没有太大影响

IV可在第三个组件中找到,组件2:

8CEBD90AFA760D42F190CCA2C9B4635F 您可以使用AES-128/ECB/PKCS7填充来解密组件3

最后,为了匹配组件4中的身份验证标记,您需要计算以下各项的HMAC-SHA-256:

A | IV |密文| AL 其中A是附加的经过身份验证的数据。这是基本64 url编码头!的ASCII编码!。最后,AL是以位表示的A长度的64位大整数,即字节数乘以8

因此,总的来说,应该是:

65794A64486B694F694A4B5634151694C434A686247636944F694A53553045543046554349496D74705A434936496B4A475444427A635670455A4574506464E245583239536C6C504E4686C62456851616C6457564231576D5A53637A42745454564D6445694C626D694D694A4254544A425454544545454545454546D694A44694A424A4245545444444444A424A42425454545454545454444444A4242424254545454545454545454454545454545454545 8CEBD90AFA760D42F190CCA2C9B4635F 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 7 7 7 7 7 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6八,E510112D2815CE66885D89E230128D64526FCC649A57CC5E8720991AB2BACD5CDFEB9598C3096D10437D9BF41816783B236FF6AE6F4CA098F7445DD056637AD382DBF62406A53A684B811AB5ABCA27FDD937E672AE87292AEBF65332DA7930F955CA50CE0E9CF0502679FDF5D866ABB9629859AD67C252038B62636363637AB647BF627CBD64372CF63637B7B7B4CFB1677B41677CBD677B41677B627B4CF636363637B7B7B7B7B416464646464647B7B7B7B627B7B7B7B7B7B7B4F19E33FE3280D5FAA79584A64404A9A2792EAA915C7E3F966546A7E3BD1F6AA46DAACF70786B50A39A760E2F3FE634E0D3D08B60A04C7DAE3160C39967962BC4706BD6216659DE1AD05BD84250C28C39117EFDB50C5925789DB70B227B663B26D824CF65793DCBA1B71F3398805C72AE2230FF9D95A67CC8AE0998B26A666B8686868CF078CF288B078B7676768CFB2788B787B077B798B798B798B798B798B798B798B798B798B798B798B798B798B798B798B798B798B798B798B08080808CFC623876CF479D8DCD329CF3EA28B31F12CF1241638B2876043A29C54C1966A560F095E9E17BF4B75FE60A5A87FA174CC3F49E7EEB29C72889FB65345B207A69F35C9337B03058A9BF7CEEF41069435FA47B3EE54393AD6A67595F9612D7B7C1D78B6CC62D06F8F117702A867F0D9D980D25E6E6B6B6B9B737B7B7B7B7B7B7B7B7B7B7B7B7B7B7B7B7B7B7B7B7B7B6B6B6B6D980D9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B2DC41B844A596269BAC540DA1899D86085B3B3DF5913C2EE148577C579D8ED61C2E66C033E81378A49BF5AC889C55224DA33320CAFF59A49E4790E4790E4C8514CEDB2EFD4AE4ADD48B5F55C020D486D86B9163F8E67CA69BBD03D24A055D784F810FB5F01C9E82CB46BF799E04F3B013AE29BF843BB93B9DAFE9E47980E4790E4C8514CEDB8B5F5050D868BF41418B498BF788B498B498BFB1788B498BFB1788B788B498B498BFB1788B788B498B785BFB1958B788B498B498B9F498B9B49B0A2D2E8BADD7DEEF7096A13503AF49BED6F41A9716FC559521DAF3DFC7EF969C3B820C61E9B79512574F665D C2C421BC567C05148DEE1FA42A5E99FEFDDA44D4EB6F003FA900D8947EB8FF3817D14AA9E8DEE8C280D1ADAB366EF36CE1262EB85ACAB533EB18407825C1BB19FD11073CDDC2AC364572F04441D396780A9407A598DEE9D004A4A28E20DECE723D3804DC064FD139C2786516A99A713C8DEFC8BA90B5676B817BD717CF647B947BAB947EB677B947B977B7B947B9EB637B7B7B947B947B7B947B947B947B947B7B7B7B7B7B947B947B947B947B947B947B947B7B947B947B7B7B7B70DC66843D802AE8B37D69C98E84E759C24368F791D985C55B96DDF4E9E42CC7A403EE4D28BACD7EABF2CB6D522F9B24AF350937B2F13305B6BE6CAA962D94B1DB5294AC8BE61F61E3427CE99230B1123104434A1ECB98115B18AF730DABEE02D334C34F5678951039E01C49C4161592C483CF9AB6D0E375CA71544640285BF457B757CFB757CFB757B757CFB757B757CFB757B757B757CFB757B757B757CFB757B757B757B757CFB757B757B757B757B757B757B757B757B757B75A34D3A1A11396AD175C0B34A1171DED15688F0518A5B54602F593EFF833D32AF9C90C500B6C0BB60FB296170D5D0A70EB516E47CF15B6EF8634C31DB97AFDC12A9544E6D7A406E8D53559AA36221 0000000000000458 请注意,最好使用时间常数比较来测试身份验证标记

然后你得到了Väinö的JWT标记,肯定是一个测试集


祝你好运

可以通过在点上拆分组件来找到组件,组件采用base 64 URL编码

标头位于开始或组件0处,它表明这是混合加密,AES-CBC和HMAC用于经过身份验证的加密

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)
您对组件1的RSA-OAEP解密成功。如果密文和密钥不匹配,OAEP将出错。但是,它不返回纯文本,而是按顺序返回一个16字节的HMAC密钥和一个16字节的AES密钥!。键值以十六进制表示:

19D7657D5CDBF41E48EB4FF35A970406 DC803B73BD16AEC1B2DF85FCBBD106F3 请注意,密钥取决于标头中设置的经过身份验证的加密算法。您可能希望首先测试该报头,以查看是否使用了可接受的算法,而不是相反的方法,因为这将启用对该算法的降级攻击,永远不要依赖安全参数的输入

顺便说一下,OAEP解密在内部使用MGF1和SHA-1,这是默认值;不要担心其中的SHA-1,散列对OAEP的安全性没有太大影响

IV可在第三个组件中找到,组件2:

8CEBD90AFA760D42F190CCA2C9B4635F 您可以使用AES-128/ECB/PKCS7填充来解密组件3

最后,为了匹配组件4中的身份验证标记,您需要计算以下各项的HMAC-SHA-256:

A | IV |密文| AL 其中A是附加的经过身份验证的数据。这是基本64 url编码头!的ASCII编码!。最后,AL是以位表示的A长度的64位大整数,即字节数乘以8

因此,总的来说,应该是:

65794A64486B694F694A4B5634151694C434A686247636944F694A53553045543046554349496D74705A434936496B4A475444427A635670455A4574506464E245583239536C6C504E4686C62456851616C6457564231576D5A53637A42745454564D6445694C626D694D694A4254544A425454544545454545454546D694A44694A424A4245545444444444A424A42425454545454545454444444A4242424254545454545454545454454545454545454545 8CEBD90AFA760D42F190CCA2C9B4635F 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 7 7 7 7 7 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6八,E510112D2815CE66885D89E230128D64526FCC649A57CC5E8720991AB2BACD5CDFEB9598C3096D10437D9BF41816783B236FF6AE6F4CA098F7445DD056637AD382DBF62406A53A684B811AB5ABCA27FDD937E672AE87292AEBF65332DA7930F955CA50CE0E9CF0502679FDF5D866ABB9629859AD67C252038B62636363637AB647BF627CBD64372CF63637B7B7B4CFB1677B41677CBD677B41677B627B4CF636363637B7B7B7B7B416464646464647B7B7B7B627B7B7B7B7B7B7B4F19E33FE3280D5FAA79584A64404A9A2792EAA915C7E3F966546A7E3BD1F6AA46DAACF70786B50A39A760E2F3FE634E0D3D08B60A04C7DAE3160C39967962BC4706BD6216659DE1AD05BD84250C28C39117EFDB50C5925789DB70B227B663B26D824CF65793DCBA1B71F3398805C72AE2230FF9D95A67CC8AE0998B26A666B8686868CF078CF288B078B7676768CFB2788B787B077B798B798B798B798B798B798B798B798B798B798B798B798B798B798B798B798B798B798B798B08080808CFC623876CF479D8DCD329CF3EA28B31F12CF1241638B2876043A29C54C1966A560F095E9E17BF4B75FE60A5A87FA174CC3F49E7EEB29C72889FB65345B207A69F35C9337B03058A9BF7CEEF41069435FA47B3EE54393AD6A67595F9612D7B7C1D78B6CC62D06F8F117702A867F0D9D980D25E6E6B6B6B9B737B7B7B7B7B7B7B7B7B7B7B7B7B7B7B7B7B7B7B7B7B7B6B6B6B6D980D9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B2DC41B844A596269BAC540DA1899D86085B3B3DF5913C2EE148577C579D8ED61C2E66C033E81378A49BF5AC889C55224DA33320CAFF59A49E4790E4790E4C8514CEDB2EFD4AE4ADD48B5F55C020D486D86B9163F8E67CA69BBD03D24A055D784F810FB5F01C9E82CB46BF799E04F3B013AE29BF843BB93B9DAFE9E47980E4790E4C8514CEDB8B5F5050D868BF41418B498BF788B498B498BFB1788B498BFB1788B788B498B498BFB1788B788B498B785BFB1958B788B498B498B9F498B9B49B0A2D2E8ADD7DEEF7096A13503AF49BED6F41A9716FC559521DAF3DFC7EF969C3B820C61E9B79512574F665DC2C421BC56C05148DEEFDA44D4EB6F003FA900D8947EBB8FF3817D14AA9E8C280D16EF36CE1262EB85ACABD53EB18407825C1B19FD11073CD2AC3652 7月6日,6月7日,6月7日,7月7日,7月7日,7月7日,7月7日,7月7日,6月7日,6月7日,7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8日,6 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 427CE99230B1123104434A1ECB98115B18AF730DABEE4C02D334C34F556789E01C49C4161592C483CF9AB6D0E375CA715446402485DBF5FAD80F8683C84E16134BEC63FA43F774B71275FDCFA61BE35B4FC8548A3FF5B5B5B5B5E1C665DC8C4B5CBA31A1396AD175C0B34A1171DED1568F0518B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5BAA363221 0000000000000458 请注意,最好使用时间常数比较来测试身份验证标记

然后你得到了Väinö的JWT标记,肯定是一个测试集


祝你好运

最终解决方案非常简单。我曾尝试将整个JSON密钥用于几个不同的库,但只使用PEM版本,不允许使用名称,而密钥存储未能找到它,即使JWE头清楚地描述了用于加密的密钥

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)

最后,解决方案非常简单。我曾尝试将整个JSON密钥用于几个不同的库,但只使用PEM版本,不允许使用名称,而密钥存储未能找到它,即使JWE头清楚地描述了用于加密的密钥

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)

不,这是自动测试数据。这里没有什么敏感的,但是谢谢你的提问!如果解密没有失败,那么答案可能是正确的,因为如果您有错误的私钥或密文,OAEP将无法解密。你能用十六进制而不是ab2str打印出你得到的数据吗?您可能得到的是OAEP解密的直接输出,这可能是128或256位AES数据密钥混合加密。然后可以用它来解密下一部分。Uint8Contents:,通过tellength 32,但首先我感到困惑的是,JWT包含五个部分-一个正常的、有符号的JWT aka。JWS包含3个部分,但是你得到了一个,一个加密的JWTNote给其他读者,上面Uint8Contents中的值不正确,它是针对不同的JWE的。不,它是自动测试数据。这里没有什么敏感的,但是谢谢你的提问!如果解密没有失败,那么答案可能是正确的,因为如果您有错误的私钥或密文,OAEP将无法解密。你能用十六进制而不是ab2str打印出你得到的数据吗?您可能得到的是OAEP解密的直接输出,这可能是128或256位AES数据密钥混合加密。然后可以用它来解密下一部分。Uint8Contents:,通过tellength 32,但首先我感到困惑的是,JWT包含五个部分-一个正常的、有符号的JWT aka。JWS包含3个部分,但是你得到了一个,一个加密的JWTNote给其他读者,上面UINT8内容中的值不正确,这是针对不同的JWE。谢谢你的时间和解释,他们教了我很多这种特殊的加密!谢谢你的时间和解释,他们教了我很多这种特殊的加密!