Do not speak Portuguese? Translate this site with Google or Bing Translator
Usando RS256 para assinar e verificar seu JWT

Posted on: August 26, 2024 02:59 PM

Posted by: Renato

Categories: jwt Oauth2

Views: 162

Usando RS256 para assinar e verificar seu JWT

Christian Eland

Quando falamos em OAuth e OpenID Connect, falamos de JWT.
Sabemos que os JWT devem ser assinados, mas qual algoritmo utilizar?

Usar um algoritmo de assinatura assimétrico no seu JWT é a melhor escolha, pois não haverá necessidade de compartilhar uma chave privada com muitas aplicações.

Usar um algoritmo como RS256 e o endpoint JWKS permite que suas aplicações confiem nos JWTs assinados.

Qual a diferença entre HS256 e RS256?

  • HS256: gera um MAC simétrico, precisa compartilhar um “secret” com qualquer cliente ou API que queira verificar o JWT. Por ser um algoritmo simétrico o mesmo “secret” é utilizado tanto na assinatura quanto na verificação. Isso significa que não há como garantir completamente que o JWT foi gerado pela fonte esperada. (como um OIDC OP, por ex)
  • RS256: gera uma assinatura assimétrica, o que significa que uma chave privada deve ser utilizada para assinatura do JWT e uma chave pública deve ser utilizada para verificar a assinatura. Isso garante que a fonte esperada assinou o JWT.

Verificando RS256

Vamos nos basear na especificação de JWK (JSON Web Key) . Essa especificação define 2 estruturas de dados de alto nível: JWKS e JWK. As definições:

  • JSON Web Key (JWK): Um objeto JSON que representa uma chave criptográfica. Os membros do objeto (JSON) representam as propriedades da chave, incluindo o valor da mesma.
  • JWK Set: Um objeto JSON que representa um conjunto de JWKs. O objeto JSON deve ter um membro “key”, que é um array de JWKs.

De uma maneira bem simples, JWKS é um conjunto de chaves contendo as chaves públicas que devem ser usadas para verificar qualquer JWT expedido pelo servidor de autorização.

Num servidor open-source Gluu, a jwks_uri fica em https://[dominio/oxauth/restv1/jwks, que retorna por exemplo:

{
"keys" : [ {
"kty" : "RSA",
"e" : "AQAB",
"use" : "sig",
"crv" : "",
"kid" : "fa834459-66c6-475a-852f-444262a07c13_sig_rs256",
"x5c" : [ "MIIDBDCCAeygAwIBAgIhAP+hWbaZnUq8Z1ERfxg9679LMgKrjaNtN02yZoh1TUbgMA0GCSqGSIb3DQEBCwUAMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwNzE0MDUzMDQxWhcNMjAwNzE2MDUzMDUwWjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtC0s/6n2mx34ls7rWRQoWdkyY56RicuzGM8xihsYV9GddfcpZhzZFedd4jRAzAonN+/1xeV0H8OvfS6w7fKZehzakOdB+Pb2d2P9V5+Ip1dBBKM+LAknWUgM61liSgwX+uHX9ej8TRn+0TCPlmA5KouUpWEPm3eD0vZUchgBbwbMpLdl8YkrIb+RjUThiJsyQKK75owQtP/wRFl/U4gEeK7oChioZyYaKGYOew3X4xQDkS/bF5ONmQzVxQawFJoPho0Ob9P2XDWtIz9tz0UieGe1wgjCF+nzz+l31p/1er8/UTjPs9gTDQDGP/GYMEocViYHS1WZ0WNSfDJGbdHPRQIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwDQYJKoZIhvcNAQELBQADggEBAHZFl9JZ6YsPr6BmAS6h6SnNRpeWX9GrfO0jhhhzsHR/UWTBMWHsb4XXKNZvnmGzsXGEDHU8ep3McgckN7Kc2X3TeZFCjUgYckZJZ61TwJcR9vyMcrPSgQBOhrtkooNYu0HDg5RExc+uwaOER9jiIFKFgQCRtwRRPox8O54HzLNc7m296DchluXtNDIxCs69PNkI2yNmNpxPgH7JXfldhlU2+vjE0G/n/zcK8aa8pCxLeqM07iqLhcYzjNhopKmC0UnwoSyKh7be4oNBk9QbCQ4rdx2zVzmaFT1IietfibGyq3/nP6VcCs0hpJ3808OznOovx3t4VH3kTg5mX8OVVbo=" ],
"exp" : 1594877450248,
"alg" : "RS256",
"n" : "tC0s_6n2mx34ls7rWRQoWdkyY56RicuzGM8xihsYV9GddfcpZhzZFedd4jRAzAonN-_1xeV0H8OvfS6w7fKZehzakOdB-Pb2d2P9V5-Ip1dBBKM-LAknWUgM61liSgwX-uHX9ej8TRn-0TCPlmA5KouUpWEPm3eD0vZUchgBbwbMpLdl8YkrIb-RjUThiJsyQKK75owQtP_wRFl_U4gEeK7oChioZyYaKGYOew3X4xQDkS_bF5ONmQzVxQawFJoPho0Ob9P2XDWtIz9tz0UieGe1wgjCF-nzz-l31p_1er8_UTjPs9gTDQDGP_GYMEocViYHS1WZ0WNSfDJGbdHPRQ"
}, {
"kty" : "RSA",
"e" : "AQAB",
"use" : "sig",
"crv" : "",
"kid" : "2fef95cb-bdb1-4d7e-af4f-e4632dab4773_sig_rs384",
"x5c" : [ "MIIDBDCCAeygAwIBAgIhAKh3wNZIJJxTMNTmZPstkG4qtuB/5tu4Uy9+2JVCDv/tMA0GCSqGSIb3DQEBDAUAMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwNzE0MDUzMDQyWhcNMjAwNzE2MDUzMDUwWjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApcTN8m+8cK1p5zahgwaC38QlqvxryXIJpyGG+O3SXiY0GxNvzvbw9vwwApXs5f8DIuH/ar1KgdOxWHzFz+RqpwlerhUffbZ9XFDcrFAqvxDr61vgRCZq6kmBpl7TYkaGAELk7jVXbz7fchtJk+Ndbg+TjYwzGuBrO6O9T0IYqzz+vcIv1uHgZdVbj/OR++UYBdgcXlxoTIHRNlwuanvOQs7wix5w4fGsAEjkVHMqqhUvbjqY28x+MeiwZ4TBiyemQg+dJRMgf51YY/HsC5VE9ZbDiJNDeKR/ccl6fUafqYii5/A+okVnfMj5GgdKOWQopmHXEWhx0+iexXYhkfJaxQIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwDQYJKoZIhvcNAQEMBQADggEBADyydujhoM5pjHmz1fwWz93Lk+xs3os2fMne9LqeG7NAMSNzB4ysOpH5Gc3cHzWEXsMpkuwpo6wqwy4LIw+mbvDSKWY/C0ShrxwGbtY0FvNEmT8NCvXw3qGxJkLF4DjXJWIIidQsytf/35mrLwlFA33D+Y9kOCEVmClhteo2EgbeBcdy4ZIiVQXowQYTFvgAtBaeg6KKgzrUoI73JR7J9cY3M7lOyKVxpcdzqxzJuZH2EUjFmkztW/D69dPJeaeHYTb6Xn+c9WYarktnKhJnLo7eZasjHzJHX9AuHoVHXF2mYN6AFihrNJO5Sgqei1ay3M+PpoInLd+kW5VYRPL4TOg=" ],
"exp" : 1594877450248,
"alg" : "RS384",
"n" : "pcTN8m-8cK1p5zahgwaC38QlqvxryXIJpyGG-O3SXiY0GxNvzvbw9vwwApXs5f8DIuH_ar1KgdOxWHzFz-RqpwlerhUffbZ9XFDcrFAqvxDr61vgRCZq6kmBpl7TYkaGAELk7jVXbz7fchtJk-Ndbg-TjYwzGuBrO6O9T0IYqzz-vcIv1uHgZdVbj_OR--UYBdgcXlxoTIHRNlwuanvOQs7wix5w4fGsAEjkVHMqqhUvbjqY28x-MeiwZ4TBiyemQg-dJRMgf51YY_HsC5VE9ZbDiJNDeKR_ccl6fUafqYii5_A-okVnfMj5GgdKOWQopmHXEWhx0-iexXYhkfJaxQ"
}, {
"kty" : "RSA",
"e" : "AQAB",
"use" : "sig",
"crv" : "",
"kid" : "639f7204-2f24-4f45-85c7-73c39ee7e4f0_sig_rs512",
"x5c" : [ "MIIDAzCCAeugAwIBAgIgB4umTv9pBV7UtaiKiFenGr8GYhBE2yxXRC9+dGHS89IwDQYJKoZIhvcNAQENBQAwITEfMB0GA1UEAwwWb3hBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMDA3MTQwNTMwNDNaFw0yMDA3MTYwNTMwNTBaMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQClu+DR3C9AQds3el8Aqm5SPTwC47ZYJtCwt26i4aJ+gGbMvio75hYFaQo6nm+f+T3owIO8oBawiBJ6bdsD0bsZ/ca36hWUxNdqmPZfbQTO9WvfqNfmaCYJosgr5eO4voKGBA2pKZ5FAu1zSkFYnlCEdLziFESS57m+F+tOrsmW9UpFp/KCDXcoNWEycCqR+NJbkOzkq9IQdskATUnn8iDWpZBMPbaxcAUkzYlHl5lV0pm8JPJ3gsd3UNC9AgXU39rJ8CULQRMhDa8yL+3M1M+inqY/a1a9OnLJXeKI1QF3arH6hJU+uXBH5rYUmqbXeKr1RtepopYLKCTrEj/KNgg9AgMBAAGjJzAlMCMGA1UdJQQcMBoGCCsGAQUFBwMBBggrBgEFBQcDAgYEVR0lADANBgkqhkiG9w0BAQ0FAAOCAQEAWTeEL5VflWhDvrNkOTlEvOqOoHnOMv/EC5i9kR4fgbfflNGgm6mlEJ4zsVuS2Q/4Xfmp4DWjRfx61Cc30LfZUhw2riUbn+SZl2hM/5CpGgch/bO/k6dFBq/g/KBKR6oWW0o8Odg93LgzZk4lSYq8XBWI0bMwYXTI4SfbcDkKJ+ZAD0YioEawQD6AXRYiSGY6b2/XGEoU/rwuYvKYevn+npEokwE4AQAAY0/VOY8ZSwS1c4xlboRzjPVlgOpdPn6uQ6rkmScXoIoE0F2qOscTAXgVOmYLLcNbnpwmVLjD5EQKQNPOZW6AWWyXY6+KXEHV3J9kedkdghTfKoG0fTB1vw==" ],
"exp" : 1594877450248,
"alg" : "RS512",
"n" : "pbvg0dwvQEHbN3pfAKpuUj08AuO2WCbQsLduouGifoBmzL4qO-YWBWkKOp5vn_k96MCDvKAWsIgSem3bA9G7Gf3Gt-oVlMTXapj2X20EzvVr36jX5mgmCaLIK-XjuL6ChgQNqSmeRQLtc0pBWJ5QhHS84hREkue5vhfrTq7JlvVKRafygg13KDVhMnAqkfjSW5Ds5KvSEHbJAE1J5_Ig1qWQTD22sXAFJM2JR5eZVdKZvCTyd4LHd1DQvQIF1N_ayfAlC0ETIQ2vMi_tzNTPop6mP2tWvTpyyV3iiNUBd2qx-oSVPrlwR-a2FJqm13iq9UbXqaKWCygk6xI_yjYIPQ"
}, {
"kty" : "EC",
"use" : "sig",
"crv" : "P-256",
"kid" : "8be2d1da-3dfd-448a-94e3-70d54cf7cc72_sig_es256",
"x5c" : [ "MIIBeDCCAR6gAwIBAgIhAPTNdOYcEwqwvt5kQUBx0PZJGSws8kcGcg6n105Rc84gMAoGCCqGSM49BAMCMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwNzE0MDUzMDQzWhcNMjAwNzE2MDUzMDUwWjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEMSrZQI5HljPZ1ABYbdmPsangmRKqg9ESbYI/UCRvJSKyr1FuAlf4QeLzaE763uVXFL2jNqf3Xa0yb8h81eQeG6MnMCUwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMAoGCCqGSM49BAMCA0gAMEUCIEaw6XDymS+DOe66yHnvkW0LhKBA31LDlE08/xMrWhIRAiEAyM/VizHxzFjz4O29jQADaCRTj0BbB0DYqrI2JfnK/C4=" ],
"x" : "MSrZQI5HljPZ1ABYbdmPsangmRKqg9ESbYI_UCRvJSI",
"y" : "sq9RbgJX-EHi82hO-t7lVxS9ozan912tMm_IfNXkHhs",
"exp" : 1594877450248,
"alg" : "ES256"
}, {
"kty" : "EC",
"use" : "sig",
"crv" : "P-384",
"kid" : "857380c4-db37-4c2c-8d57-3e46fa988eb5_sig_es384",
"x5c" : [ "MIIBtjCCATugAwIBAgIhAMBZAcWyyC2NKQy04Hx7x/vZoPaGHqY28vjpal/aX5y+MAoGCCqGSM49BAMDMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwNzE0MDUzMDQzWhcNMjAwNzE2MDUzMDUwWjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEiqU4Bh9jCprZvOh4lG5skbGTfX0Ykt+p5SLGSU/Gr2J5Kd4R377zzfko970ANsVBXc3RYSWrcd8WXjxRPbWyDjrk2ii+VYe1Lr77xpZgfOJDWkVgjSaT1ee6NV87o0j8oycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwCgYIKoZIzj0EAwMDaQAwZgIxAIFNhgsykTlHnB20yAviQs0iM1WgX2apgXPl0oGe2j3yobpR2SWV+cUi5stiECyv9AIxAPH+ywcHirxbva4GXNt82hKyBlKOxoMbEHeSHEqBVo1nK45EPIje6NRRmGSjbcYniA==" ],
"x" : "iqU4Bh9jCprZvOh4lG5skbGTfX0Ykt-p5SLGSU_Gr2J5Kd4R377zzfko970ANsVB",
"y" : "Xc3RYSWrcd8WXjxRPbWyDjrk2ii-VYe1Lr77xpZgfOJDWkVgjSaT1ee6NV87o0j8",
"exp" : 1594877450248,
"alg" : "ES384"
}, {
"kty" : "EC",
"use" : "sig",
"crv" : "P-521",
"kid" : "4f64c2c8-6695-4a72-9dc4-554da04abc0f_sig_es512",
"x5c" : [ "MIIB/zCCAWGgAwIBAgIhALggJWY04HI04iGYLP5qcrMz+8zuZN4kkehx3A0jWPvDMAoGCCqGSM49BAMEMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwNzE0MDUzMDQ0WhcNMjAwNzE2MDUzMDUwWjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAoaTVRxWZzGW+CR140ceVtQulG8XX4ZSNab60oSYpMAsGl8sQstDTZRUrIJP2x8BdE8aniLcJ7LH2fbXB+oFf+d8AJ89PJ+SIVd5EwK2p5GYHqP87+GpCJSn7U4hnIbUgQsuOxiRy5g+jQn4cfzfa7emHUOw+OcmIkPg5MERFxRa/lUyjJzAlMCMGA1UdJQQcMBoGCCsGAQUFBwMBBggrBgEFBQcDAgYEVR0lADAKBggqhkjOPQQDBAOBiwAwgYcCQgECZmha1CCkrpCqs6WgByn7asvzOj93lU3aadboI9O+pUmlvAOT5YSeKXgbcsQ98eGA5Xh4q/bLTSqZg1JqnV/wGgJBeygLNnYXEilCx+uKcKbyU+kDBLoGt64ToxnIeBPmsZrxprx/XFP9CP8WEJmUkJwt4OfT5P0keGY2t9INCgbCXrw=" ],
"x" : "oaTVRxWZzGW-CR140ceVtQulG8XX4ZSNab60oSYpMAsGl8sQstDTZRUrIJP2x8BdE8aniLcJ7LH2fbXB-oFf-d8",
"y" : "J89PJ-SIVd5EwK2p5GYHqP87-GpCJSn7U4hnIbUgQsuOxiRy5g-jQn4cfzfa7emHUOw-OcmIkPg5MERFxRa_lUw",
"exp" : 1594877450248,
"alg" : "ES512"
}, {
"kty" : "RSA",
"e" : "AQAB",
"use" : "sig",
"crv" : "",
"kid" : "7b0cbe98-54cb-48ba-8a2c-1feb452abf16_sig_ps256",
"x5c" : [ "MIIDazCCAh+gAwIBAgIgLb6FJs95PGb+iFA8tNyIMxA6MI5N1HYnSiuhGiRWpkwwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEFAKIDAgEgMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwNzE0MDUzMDQ0WhcNMjAwNzE2MDUzMDUwWjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv/bumTlLseqNPOXOdfNtrPZxOfJVNZDxbkFMThsNUxuoXKGN9Z2D1i6puHwZI1w/I38VKpTTBKfHspKnSMevSh2pKKDLWRtU+F0jHZAd9BFt5texNGjbsJOHjkKw6eTSQTEScSQcyMjhTBnmc0BqmfB0pTy3OUKxspEBpJytvc+Wax7dKiVcGdUarEdd2pXkJRxJuYVI+tKpw4xpVSPXJTbn8u2Cp+2r8ZjDOAetlc3EgEOOuvNdjb22cpX/VN0J5OzxZE1N+hK1a+GLhka+u9k5SBec+SYajB7ocopGhA2fRCWoKQ5X1Ijjb54Omx88yZsXqr5rOK0ugEjkRDZiYwIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEFAKIDAgEgA4IBAQCAb/azcibVFof5NJgodVI59+hHX02c7uNovCeiWrZuHLf8eTa8PtR8r0v2STxISD/46Mh2LISu/F07p6b4Ij5HWFswZDwzCTeRdKIEYmMsigDo65r41T+oCu2jltyBty16Us6UpS1k2gO5aYPkM0P4v7IpXvlcY2JUZEMRUOhpXS5gIYTU0ESGDReSM0blk2hIMuf/xeMjn3tr2UA1JKzW/Qu01tw1sStiHc74NkIou+hopKVcMMpOKUocmPK0x4bmijBzNACMz+r+oUQPKn2esA1uzxqRutp/0RBf5RQoBu8qZF7uIBc9q1MbwS6f/On3RAXg8Gv/bgsQ5kmf7xAn" ],
"exp" : 1594877450248,
"alg" : "PS256",
"n" : "v_bumTlLseqNPOXOdfNtrPZxOfJVNZDxbkFMThsNUxuoXKGN9Z2D1i6puHwZI1w_I38VKpTTBKfHspKnSMevSh2pKKDLWRtU-F0jHZAd9BFt5texNGjbsJOHjkKw6eTSQTEScSQcyMjhTBnmc0BqmfB0pTy3OUKxspEBpJytvc-Wax7dKiVcGdUarEdd2pXkJRxJuYVI-tKpw4xpVSPXJTbn8u2Cp-2r8ZjDOAetlc3EgEOOuvNdjb22cpX_VN0J5OzxZE1N-hK1a-GLhka-u9k5SBec-SYajB7ocopGhA2fRCWoKQ5X1Ijjb54Omx88yZsXqr5rOK0ugEjkRDZiYw"
}, {
"kty" : "RSA",
"e" : "AQAB",
"use" : "sig",
"crv" : "",
"kid" : "f5dcc755-bd1a-49ac-b86d-0c193ec41ce8_sig_ps384",
"x5c" : [ "MIIDazCCAh+gAwIBAgIgJywNmJ6J0dIurCySZLTi0bYOPioEO2d1+a2kxOuVp+AwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgIFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgIFAKIDAgEwMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwNzE0MDUzMDQ1WhcNMjAwNzE2MDUzMDUwWjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyABl2vKVxIkMAAzzsxpzpvjWizPFoITc6tlJWjJoNQtjSDANPEkKynl9XuzBf9V5gsbCdygTUa+1EYJabx/cmN0v355qZFhN1F8YecfnkZ/iRLSgN7/1/4edx96vj0DKFIhDpMOr3L3lLEnA2OSwdZ+7yvLzzwbRVa469a/Be/lYGWsxL3tQGpnmszQjiQuktuJgcFv+xa86lgtEW7Hj+5YZp6+ztbZw74ok1cPqwL7kebBXwszS/5WdsyS2KSaj4olYZBXVijFhNgVNxA2/9tyYUPYt9vDbr0s5mDsQE1unOb1EwLfs/diVmKSk/3liZT4bQdu+BqD4mhwcr3sPtwIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgIFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgIFAKIDAgEwA4IBAQAcF7auD5v928X11ib7GVxCoLkvC3arYQ41f+9TmqPYHZaGdeT8aA5wBiWFjEPquAzMPb3oI8e7opQylSz3XJaTONdGW0mkAc+KkDVIZdefxyo20wCmCBTU4JBcJPiv9BpYsu5gUSjXqEbLRr3tSBA70gO3dhFaLA2okMwnm0U3peMJCX75n0d2/Vmq9Zkny7QqKviegj9c5VHA71z7TPxkRjYBDKO6mPfwFpW0w/ycMBQxQp5rW3t5fjGuBN/OYC8thsQzhq83WtFaErEf1/O7hp65it8Qn6zeeGVYt7Y2mSKFRJt4opkvJauFmmbhYoRk1zmahovRlwzNg5CU4/yR" ],
"exp" : 1594877450248,
"alg" : "PS384",
"n" : "yABl2vKVxIkMAAzzsxpzpvjWizPFoITc6tlJWjJoNQtjSDANPEkKynl9XuzBf9V5gsbCdygTUa-1EYJabx_cmN0v355qZFhN1F8YecfnkZ_iRLSgN7_1_4edx96vj0DKFIhDpMOr3L3lLEnA2OSwdZ-7yvLzzwbRVa469a_Be_lYGWsxL3tQGpnmszQjiQuktuJgcFv-xa86lgtEW7Hj-5YZp6-ztbZw74ok1cPqwL7kebBXwszS_5WdsyS2KSaj4olYZBXVijFhNgVNxA2_9tyYUPYt9vDbr0s5mDsQE1unOb1EwLfs_diVmKSk_3liZT4bQdu-BqD4mhwcr3sPtw"
}, {
"kty" : "RSA",
"e" : "AQAB",
"use" : "sig",
"crv" : "",
"kid" : "9a18f584-52cd-4917-8c74-a3797b2070f3_sig_ps512",
"x5c" : [ "MIIDazCCAh+gAwIBAgIgErwFJBV9ENFMoq+ftB4seM12nXyBdZ0pz7JbbNJUNTkwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgMFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgMFAKIDAgFAMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwNzE0MDUzMDQ1WhcNMjAwNzE2MDUzMDUwWjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsOP0DrkUMb0tDOh8mpmjfn9shZZljcp/tV7zhZt05o+0MM8RGLepDQZWcfnFiuq1kqY3iJeuz9oGfGI+80/KAX0oaVquMuSA+yMbbG/NY7BiQjNCiOBgwTpdAxiLj6zWtrRyq38r1rF3+nI/j5beN8BmBB7c0OSP8GnGKYThQtbALixOTLY9U28dvUKzCupsEH994aYJxaAZdDq+Q95R7khIYCgjeCrEu3RPl1UHenxeEe8UOT5tcehljgIt3cJtej5NYoQMhTOs1Cxpepdsxo7ZE/iV5WUqMr6J5zUDHS4DJ3bfCr+6/XVwt1Dxsd7YtfBPRng6mzE/GMNIIrF95QIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgMFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgMFAKIDAgFAA4IBAQBLk9Oz75eLTXFZggyENk7nWqzjNzvJg6t3zGKz7UCMdAtS9ftEMpkofQ04vddW5b7jOv64cDi1uIDSNlptcUpON9moRL9AVIVRRb8EwoiMpCnPaViBFVKA5k6cbSqDCa5VAiEXwz+YiQ/drrPTm2id3hyn9cuFo2Usrvh8rarCY+vuJXeUX9vYos/81ICfAUeetUHmLu+r7jwLtnuy3CfVllhIvyOl1/VMMzayYIjEu9T8aQij9opW9LiNwtq82eCRhzJNy93sZ3QuMU4CjNjx/ucHQWSWeyhDJhHzvGTR1iLRIsQvM2SJS/6rhBnUuJzBBh2aVnfKYNj4bPaLWpNg" ],
"exp" : 1594877450248,
"alg" : "PS512",
"n" : "sOP0DrkUMb0tDOh8mpmjfn9shZZljcp_tV7zhZt05o-0MM8RGLepDQZWcfnFiuq1kqY3iJeuz9oGfGI-80_KAX0oaVquMuSA-yMbbG_NY7BiQjNCiOBgwTpdAxiLj6zWtrRyq38r1rF3-nI_j5beN8BmBB7c0OSP8GnGKYThQtbALixOTLY9U28dvUKzCupsEH994aYJxaAZdDq-Q95R7khIYCgjeCrEu3RPl1UHenxeEe8UOT5tcehljgIt3cJtej5NYoQMhTOs1Cxpepdsxo7ZE_iV5WUqMr6J5zUDHS4DJ3bfCr-6_XVwt1Dxsd7YtfBPRng6mzE_GMNIIrF95Q"
}, {
"kty" : "RSA",
"e" : "AQAB",
"use" : "enc",
"crv" : "",
"kid" : "1b1ae329-8a1b-4f8f-98ad-29fc6fb8460e_enc_rsa1_5",
"x5c" : [ "MIIDAzCCAeugAwIBAgIgYxr5V3K2YXCbxGaZWnkktQCIC4IJoBQtt5O6D3BNzHUwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWb3hBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMDA3MTQwNTMwNDZaFw0yMDA3MTYwNTMwNTBaMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDC7dGs8+YVgV2bgPC9GHELYPvRmxE278g/nWdlaNhgci2LxmRPFmKLV2vJkOHGh7UguoLw6T3NT8xKm75UfwOoUmeQUOzx1wcuL29I0fNBfMS2SsAR844STstXW/jQyjB0NpqfQ9wOJfY5NWcrEfYJI1x5/YT5u8mtG+2Bez3Qjz58tE3kgymSbQfN4IWZo54zqbW95NjdcxsUbRcYEOL4oErmrig4IpfJMCheEGeX1rNqFgEiu8G8tcYEv8o7cA6lsGRlfQf/juxAf9lHgMLA4yIE9Pjx3+isupMNP22WQMxUQa3dfV4+aQB7HhvKfOQEMvkQxc59tnNNsQWs6R1JAgMBAAGjJzAlMCMGA1UdJQQcMBoGCCsGAQUFBwMBBggrBgEFBQcDAgYEVR0lADANBgkqhkiG9w0BAQsFAAOCAQEAA0X1xdZX2+1i7UusltyrUFHcb4cuyJUmDuJ4S5f3Ei1xijRds4ItET40KaY1SSySwUoLdKAMxbOGNRjvILeyozbbveO73wS5nHLeOku3te7bvGC7ZqIJWWqEby38uHvs6tiLvHZ+uz9hjgqDM88HGFpGijVaDlN09E28wnHyIpcF1EXglJSofpzwLRc6PX4IrwhbPKRKiT+ejPlgABN5lb8S+6RF9txVVozIc/6lG2Ah/YpcYkgh7/pRiVuBYSPKalo2V8l8yJTBWz/zfrU9CNioADQtar66EzhQvsNbQ6WpPZ81KooWRcJwVPI1XJ76weHz9/nzYHfDqtfOGVZ6Rw==" ],
"exp" : 1594877450248,
"alg" : "RSA1_5",
"n" : "wu3RrPPmFYFdm4DwvRhxC2D70ZsRNu_IP51nZWjYYHIti8ZkTxZii1dryZDhxoe1ILqC8Ok9zU_MSpu-VH8DqFJnkFDs8dcHLi9vSNHzQXzEtkrAEfOOEk7LV1v40MowdDaan0PcDiX2OTVnKxH2CSNcef2E-bvJrRvtgXs90I8-fLRN5IMpkm0HzeCFmaOeM6m1veTY3XMbFG0XGBDi-KBK5q4oOCKXyTAoXhBnl9azahYBIrvBvLXGBL_KO3AOpbBkZX0H_47sQH_ZR4DCwOMiBPT48d_orLqTDT9tlkDMVEGt3X1ePmkAex4bynzkBDL5EMXOfbZzTbEFrOkdSQ"
}, {
"kty" : "RSA",
"e" : "AQAB",
"use" : "enc",
"crv" : "",
"kid" : "c0baf666-eb51-4647-b8ac-84ebb05d341c_enc_rsa-oaep",
"x5c" : [ "MIIDAzCCAeugAwIBAgIgQsY6XuS1YBG7DxU7V9nQUE1wavHbiySrVIQAQZ3hXvgwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWb3hBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMDA3MTQwNTMwNDZaFw0yMDA3MTYwNTMwNTBaMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCWVYhxbWCcRJ29/d66rZxqz9DfYi9Jfk1aehJZPqfu3sq+8N9VMegTXd9Hmix4bbgMaoAFBcFcseiABBQKcTG3fun04PDNQpQj3RgzuMhg3iWRaaM87y59jI9ROgYcSdtQIO8ObR2zzq7i+Wt44j+tna+MDv6md2ehhYfWlqLCuj9WhIZUqQkRTR910AJyZuEBGfTZ9Wey7mDHXzdSHjtr3TKb5whPTSrMwrlIT5KqeXsORLlO0Y4U17UQCZzCUMy3hHT9bctLHoLH3RbwxK69/5WgVNzEam22LiNU6ApyQVGD11EtiKcInlVuA9Jr55xtHZqSFn57B8hsubU2P7k7AgMBAAGjJzAlMCMGA1UdJQQcMBoGCCsGAQUFBwMBBggrBgEFBQcDAgYEVR0lADANBgkqhkiG9w0BAQsFAAOCAQEADON8Dcuq797gOxYkKAqNkE39M7tsdbl4C3Erjyj6H0pIiko8p7mkvqgLmERgdNPrFt+h97kPrmEJ8olf41/NOaOcIjP1l+xSLYp+O6lgVuzgIca7uKsn9JGppeswMWu+7m1BrK+TWPBRmzK560vUP2Ky+GFeH/Y/kslgM/IZyP+UQvpOZpE+KTFwGFZefDaVGf7xgwnYJ8113WVj6CaGj5oGjOnwy4y6mMDaPASD5kLGxbly5ns5LMRmu4xCMsqmxbIGlel20ExTyCkCGXfJ33RQ8rpUy55MCv3ThJ43Yg3hwztlaYX8sg4wQ7Y8nj/pci0Ct7Ey1cRsXlWSyhhCAg==" ],
"exp" : 1594877450248,
"alg" : "RSA-OAEP",
"n" : "llWIcW1gnESdvf3euq2cas_Q32IvSX5NWnoSWT6n7t7KvvDfVTHoE13fR5oseG24DGqABQXBXLHogAQUCnExt37p9ODwzUKUI90YM7jIYN4lkWmjPO8ufYyPUToGHEnbUCDvDm0ds86u4vlreOI_rZ2vjA7-pndnoYWH1paiwro_VoSGVKkJEU0fddACcmbhARn02fVnsu5gx183Uh47a90ym-cIT00qzMK5SE-Sqnl7DkS5TtGOFNe1EAmcwlDMt4R0_W3LSx6Cx90W8MSuvf-VoFTcxGptti4jVOgKckFRg9dRLYinCJ5VbgPSa-ecbR2akhZ-ewfIbLm1Nj-5Ow"
} ]
}

Vemos 10 chaves utilizadas para assinatura e encriptação.

Entendendo os campos:

  • alg: é o algoritmo utilizado na chave
  • kty: o tipo de chave
  • use: é pra que a chave deveria ser utilizada
  • x5c: é a corrente do certificado x509
  • e: é o exponente para um pem padrão
  • n: é o mod para uma pem padrão
  • kid: é o único identificador da chave
  • x5t: é o SHA-1 thumbprint do certificado x.509

Como verificar um JWT utilizando o endpoint JWKS?

Vou exemplificar um fluxo de autorização OIDC:

Fluxo de autorização OIDC (openid connect) utilizando JWS / JWKS

Existem várias libs para facilitar a vida dos desenvolvedores (dá uma olhadinha no jwt.io para obter a lista completa). Entre elas a authlib para Python que eu contribuo, e a jsonwebtoken para Node.js.

Basicamente o que a gente vai fazer aqui é:

  1. Decodificar o JWT e pegar a propriedade kid que tem o id da chave utilizada para esse JWT
  2. Encontrar a chave utilizada no conjunto JWKS encontrado no jwks_uri do OP.
  3. Usar a propriedade x5c para gerar o certificado que será utilizado para verificar a assinatura do JWT.

Mão na massa…

Vamos de… Node.js? (já que tenho menos experiência…)

Utilizaremos o pacote jsonwebtoken.

Lembrando que o objetivo é apenas entender a lógica, deixo os tratamentos de erro e as boas práticas com vocês.

Criarei a constante MOCKED_JWSpara utilizarmos como token, que foi criado por chris.gluutwo.org.

Vamos a um exemplo de Node.js:

Output:

Nesse caso, a função retorna o payload do JWT apenas se a assinatura estiver verificada, e também já faz algumas validações. Se você rodar esse mesmíssimo código agora, o jwt.verify()vai retornar um erro de token expirado (já que essa é uma das validações que o verify()faz).

Espero que o post tenha sido útil :)

#Jwt #Rs256 #SecurityToken #OpenidConnect #Oauth

- https://medium.com/@eland.christian/usando-rs256-para-assinar-e-verificar-seu-jwt-4cf3f7b454fd


13

Share

Donate to Site


About Author

Renato

Developer

Add a Comment
Comments 0 Comments

No comments yet! Be the first to comment

Blog Search


Categories

OUTROS (16) Variados (109) PHP (133) Laravel (171) Black Hat (3) front-end (29) linux (114) postgresql (39) Docker (28) rest (5) soap (1) webservice (6) October (1) CMS (2) node (7) backend (13) ubuntu (56) devops (25) nodejs (5) npm (3) nvm (1) git (8) firefox (1) react (7) reactnative (5) collections (1) javascript (7) reactjs (8) yarn (0) adb (1) Solid (2) blade (3) models (1) controllers (0) log (1) html (2) hardware (3) aws (14) Transcribe (2) transcription (1) google (4) ibm (1) nuance (1) PHP Swoole (5) mysql (31) macox (4) flutter (1) symfony (1) cor (1) colors (2) homeOffice (2) jobs (3) imagick (2) ec2 (1) sw (1) websocket (2) markdown (1) ckeditor (1) tecnologia (14) faceapp (1) eloquent (14) query (4) sql (40) ddd (3) nginx (9) apache (4) certbot (1) lets-encrypt (3) debian (12) liquid (1) magento (2) ruby (1) LETSENCRYPT (1) Fibonacci (1) wine (1) transaction (1) pendrive (1) boot (1) usb (1) prf (1) policia (2) federal (1) lucena (1) mongodb (4) paypal (1) payment (1) zend (1) vim (4) ciencia (6) js (1) nosql (1) java (1) JasperReports (1) phpjasper (1) covid19 (1) saude (1) athena (1) cinnamon (1) phpunit (2) binaural (1) mysqli (3) database (42) windows (6) vala (1) json (2) oracle (1) mariadb (4) dev (12) webdev (24) s3 (4) storage (1) kitematic (1) gnome (2) web (2) intel (3) piada (1) cron (2) dba (18) lumen (1) ffmpeg (2) android (2) aplicativo (1) fedora (2) shell (4) bash (3) script (3) lider (1) htm (1) csv (1) dropbox (1) db (3) combustivel (2) haru (1) presenter (1) gasolina (1) MeioAmbiente (1) Grunt (1) biologia (1) programming (22) performance (3) brain (1) smartphones (1) telefonia (1) privacidade (1) opensource (3) microg (1) iode (1) ssh (3) zsh (2) terminal (3) dracula (1) spaceship (1) mac (2) idiomas (1) laptop (2) developer (37) api (5) data (1) matematica (1) seguranca (2) 100DaysOfCode (9) hotfix (1) documentation (1) laravelphp (10) RabbitMQ (3) Elasticsearch (1) redis (2) Raspberry (4) Padrao de design (4) JQuery (1) angularjs (4) Dicas (43) Kubernetes (3) vscode (2) backup (1) angular (3) servers (2) pipelines (1) AppSec (1) DevSecOps (4) rust (1) RustLang (1) Mozilla (1) algoritimo (1) sqlite (1) Passport (2) jwt (5) security (2) translate (1) kube (2) iot (1) politica (2) bolsonaro (1) flow (1) podcast (1) Brasil (1) containers (3) traefik (1) networking (1) host (1) POO (2) microservices (2) bug (1) cqrs (1) arquitetura (3) Architecture (4) sail (3) militar (1) artigo (1) economia (1) forcas armadas (1) ffaa (1) autenticacao (2) autorizacao (2) authentication (4) authorization (3) NoCookies (1) wsl (4) memcached (1) macos (2) unix (2) kali-linux (1) linux-tools (5) apple (1) noticias (2) composer (1) rancher (1) k8s (1) escopos (1) orm (1) jenkins (4) github (5) gitlab (3) queue (1) Passwordless (1) sonarqube (1) phpswoole (1) laraveloctane (1) Swoole (1) Swoole (1) octane (1) Structurizr (1) Diagramas (1) c4 (1) c4-models (1) compactar (1) compression (1) messaging (1) restfull (1) eventdrive (1) services (1) http (1) Monolith (1) microservice (1) historia (1) educacao (1) cavalotroia (1) OOD (0) odd (1) chatgpt (1) openai (3) vicuna (1) llama (1) gpt (1) transformers (1) pytorch (1) tensorflow (1) akitando (1) ia (1) nvidia (1) agi (1) guard (1) multiple_authen (2) rpi (1) auth (1) auth (1) livros (2) ElonMusk (2) Oh My Zsh (1) Manjaro (1) BigLinux (2) ArchLinux (1) Migration (1) Error (1) Monitor (1) Filament (1) LaravelFilament (1) replication (1) phpfpm (1) cache (1) vpn (1) l2tp (1) zorin-os (1) optimization (1) scheduling (1) monitoring (2) linkedin (1) community (1) inteligencia-artificial (2) wsl2 (1) maps (1) API_KEY_GOOGLE_MAPS (1) repmgr (1) altadisponibilidade (1) banco (1) modelagemdedados (1) inteligenciadedados (4) governancadedados (1) bancodedados (2) Observability (1) picpay (1) ecommerce (1) Curisidades (1) Samurai (1) KubeCon (1) GitOps (1) Axios (1) Fetch (1) Deepin (1) vue (4) nuxt (1) PKCE (1) Oauth2 (2) webhook (1) TypeScript (1) tailwind (1) gource (2)

New Articles



Get Latest Updates by Email