Programing

JWT를 해독 할 수 있다면 어떻게 안전합니까?

lottogame 2020. 4. 12. 10:12
반응형

JWT를 해독 할 수 있다면 어떻게 안전합니까?


JWT를 얻었고 페이로드를 디코딩 할 수 있다면 어떻게 안전합니까? 헤더에서 토큰을 가져 와서 페이로드에서 사용자 정보를 디코딩하고 변경 한 다음 동일한 올바른 인코딩 된 비밀로 다시 보낼 수는 없습니까?

나는 그들이 안전해야한다는 것을 알고 있지만 기술을 정말로 이해하고 싶습니다. 내가 무엇을 놓치고 있습니까?


JWT는 서명, 암호화 또는 둘 다 가능합니다. 토큰이 서명되었지만 암호화되지 않은 경우 모든 사람이 토큰의 내용을 읽을 수 있지만 개인 키를 모르면 변경할 수 없습니다. 그렇지 않으면 수신자는 서명이 더 이상 일치하지 않음을 알 수 있습니다.

귀하의 의견에 대한 답변 : 귀하의 의견을 올바르게 이해했는지 확실하지 않습니다. 디지털 서명을 알고 이해하고 있습니까? 한 변형 (HMAC, 대칭이지만 다른 많은 변형)에 대해 간단히 설명하겠습니다.

Alice가 JWT를 Bob에게 보내려고한다고 가정 해 봅시다. 둘 다 공유 비밀을 알고 있습니다. Mallory는 그 비밀을 모르지만 JWT를 방해하고 변경하기를 원합니다. 이를 방지하기 위해 Alice Hash(payload + secret)는이를 서명으로 계산 하고 추가합니다.

메시지를 수신 할 때 Bob은 Hash(payload + secret)서명이 일치하는지 확인하기 위해 계산할 수도 있습니다 . 그러나 Mallory가 콘텐츠에서 무언가를 변경하면 일치하는 서명 ()을 계산할 수 없습니다 Hash(newContent + secret). 그녀는 그 비밀을 알지 못하고 그것을 찾을 방법이 없습니다. 즉, 그녀가 무언가를 변경하면 서명이 더 이상 일치하지 않으며 Bob은 더 이상 JWT를 수락하지 않습니다.

다른 사람에게 메시지를 보내고에 {"id":1}서명 한다고 가정 해 봅시다 Hash(content + secret). (+는 단지 연결입니다). SHA256 Hash 함수를 사용하며 서명은 다음과 같습니다 330e7b0775561c6e95797d4dd306a150046e239986f0a1373230fda0235bda8c. 이제 당신 차례입니다 : Mallory의 역할을하고 메시지에 서명하십시오 {"id":2}. 내가 사용한 비밀을 모르기 때문에 할 수 없습니다. 수신자가 비밀을 알고 있다고 가정하면 메시지의 서명을 계산하고 올바른지 확인할 수 있습니다.


로 이동 jwt.io하여 토큰을 붙여넣고 내용을 읽을 수 있습니다. 이것은 많은 사람들에게 처음에는 문제가됩니다.

짧은 대답은 JWT가 암호화와 관련이 없다는 것입니다. 유효성 검사가 중요합니다. 즉, "이 토큰의 내용을 조작 했습니까?"라는 답변을 항상 얻을 수 있습니까? 이것은 서버가 토큰을 알고 무시하기 때문에 JWT 토큰의 사용자 조작은 쓸모가 없다는 것을 의미합니다. 서버는 클라이언트에 토큰을 발행 할 때 페이로드를 기반으로 서명을 추가합니다. 나중에 페이로드와 일치하는 서명을 확인합니다.

논리적 인 질문은 암호화 된 내용과 관련이없는 동기는 무엇입니까?

  1. 가장 간단한 이유는 이것이 대부분 해결 된 문제라고 가정하기 때문입니다. 예를 들어 웹 브라우저와 같은 클라이언트를 처리하는 경우 JWT 토큰을 쿠키 secure + httpsOnly(Javascript로 읽을 수없고 HTTP로 읽을 수 없음)에 저장하고 암호화 된 채널을 통해 서버와 통신 할 수 있습니다 ( HTTPS). 서버와 클라이언트 사이에 보안 채널이 있다는 것을 알게되면 JWT 또는 원하는 다른 것을 안전하게 교환 할 수 있습니다.

  2. 이것은 일을 단순하게 유지합니다. 간단한 구현으로 채택이 쉬워 지지만 각 계층에서 가장 잘 수행 할 수 있습니다 (HTTPS에서 암호화 처리).

  3. JWT는 민감한 데이터를 저장하기위한 것이 아닙니다. 서버가 JWT 토큰을 수신하여 유효성을 검증 한 후에는 해당 사용자에 대한 추가 정보 (권한, 우편 주소 등)를 위해 자체 데이터베이스에서 사용자 ID를 자유롭게 검색 할 수 있습니다. 이는 JWT의 크기를 작게 유지하고 모든 사람이 JWT에 민감한 데이터를 보관하지 않기 때문에 부주의 한 정보 유출을 방지합니다.

쿠키 자체의 작동 방식과 크게 다르지 않습니다. 쿠키에는 종종 암호화되지 않은 페이로드가 포함됩니다. HTTPS를 사용하는 경우 모든 것이 좋습니다. 그렇지 않은 경우 민감한 쿠키 자체를 암호화하는 것이 좋습니다. 그렇게하지 않으면 중간자 (man-in-the-middle) 공격이 가능합니다. 프록시 서버 나 ISP가 쿠키를 읽은 다음 나중에 사용자 척에 따라 쿠키를 재생합니다. 비슷한 이유로 JWT는 항상 HTTPS와 같은 보안 계층을 통해 교환되어야합니다.


JWT (Json Web Token)의 내용은 본질적으로 안전하지 않지만 토큰 인증을 확인하기위한 기본 제공 기능이 있습니다. JWT는 마침표로 구분 된 세 개의 해시입니다. 세 번째는 서명입니다. 공개 / 개인 키 시스템에서 발급자는 해당 공개 키로 만 확인할 수있는 개인 키로 토큰 서명에 서명합니다.

발급자와 검증 자의 차이점을 이해하는 것이 중요합니다. 토큰 수령인은이를 확인해야합니다.

웹 애플리케이션에서 JWT를 안전하게 사용하는 데는 두 가지 중요한 단계가 있습니다. 1) 암호화 된 채널을 통해 전송하고 2) 서명을 받으면 즉시 서명을 확인합니다. 공개 키 암호화의 비대칭 특성으로 인해 JWT 서명 확인이 가능합니다. 공개 키는 일치하는 개인 키로 JWT에 서명했는지 확인합니다. 다른 키 조합은이 확인을 수행 할 수 없으므로 가장 시도를 방지합니다. 이 두 단계를 수행하면 JWT의 신뢰성을 수학적으로 확실하게 보장 할 수 있습니다.

추가 정보 : 공개 키는 서명을 어떻게 확인합니까?


서버에있는 JWT의 privateKey 만 암호화 된 JWT를 해독합니다. privateKey를 아는 사람들은 암호화 된 JWT를 해독 할 수 있습니다.

서버의 안전한 위치에서 privateKey를 숨기고 다른 사람에게 privateKey를 말하지 마십시오.


jwt.io에 존재하지 않는 특수 알고리즘을 사용하여 JWE를 살펴 보는 것이 좋습니다.

참조 링크 : https://www.npmjs.com/package/node-webtokens

jwt.generate('PBES2-HS512+A256KW', 'A256GCM', payload, pwd, (error, token) => {
  jwt.parse(token).verify(pwd, (error, parsedToken) => {
    // other statements
  });
});

이 답변이 너무 늦었거나 이미 길을 찾았을 수도 있지만 여전히 귀하와 다른 사람들에게도 도움이 될 것이라고 생각했습니다.

내가 만든 간단한 예 : https://github.com/hansiemithun/jwe-example


나처럼 비싼 데이터베이스 쿼리를 감당할 수없는 사람들을 위해 민감한 데이터 (사용자 권한 등)를 유지하는 한 가지 옵션은 JWT를 생성 할 때이 데이터를 암호화하여 JWT 토큰에 첨부 할 수 있습니다. (백엔드에 암호화 키를 보관하십시오)

민감한 정보를 읽으려면 JWT 토큰을 백엔드로 보내고 해독하여 정보를 다시 얻을 수 있습니다. 이러한 방식으로 JWT 토큰을 통해 DB 조회를 수행하거나 프런트 엔드에서 민감한 정보를 알 필요가 없습니다.

참고 URL : https://stackoverflow.com/questions/27301557/if-you-can-decode-jwt-how-are-they-secure

반응형