JWT 서명 및 검증
JWT 서명에 사용되는 암호학적 원리와 토큰의 무결성 및 진위를 검증하는 방법을 배웁니다.
JWT 서명 및 검증은(는) CoddyKit의 무료 Spring Security 6 & JWT Authentication 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Spring Security 6 & JWT Authentication 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Spring Security 6 & JWT Authentication 강의에는 총 4개의 강의가 포함되어 있습니다.
이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.
What is JWT Signing?
JSON Web Tokens (JWTs) are powerful, but how do we trust them? Signing is the answer! It's a cryptographic process that ensures a token hasn't been tampered with and comes from a trusted source.
- Integrity: Confirms the token's content hasn't been changed since it was issued.
- Authenticity: Verifies the token was issued by the expected sender.
Without a signature, anyone could create or alter a JWT!
Keys to Security: The Secret
For symmetric signing algorithms like HMAC (e.g., HS256), a single secret key is used. This key is known only to the issuer and the intended verifier(s).
- The secret key is a string of bytes, crucial for both signing and verifying.
- It must be kept highly confidential.
- If the secret key is compromised, your JWTs are no longer secure!
Algorithms: HS256 & RS256
JWTs use cryptographic algorithms to create the signature. The algorithm type is specified in the token's header.
- HS256 (HMAC SHA-256): A symmetric algorithm. Uses a single secret key for both signing and verification. Simpler to implement.
- RS256 (RSA SHA-256): An asymmetric algorithm. Uses a private key for signing and a public key for verification. More complex but better for distributed systems.
We'll focus on HS256 for our examples due to its simplicity.
Building the Signature (HS256)
The signature is created by combining the Base64Url encoded header, the Base64Url encoded payload, and your secret key using the chosen algorithm.
- Take the Base64Url encoded header.
- Take the Base64Url encoded payload.
- Concatenate them with a dot:
encodedHeader + "." + encodedPayload. - Hash this combined string using HMAC SHA-256 with your secret key.
- Base64Url encode the resulting hash to get the final signature.
Result: encodedHeader.encodedPayload.signature
Code: Generating HS256 Signature
Here's a Java example to generate an HS256 signature for a JWT. Notice how the secret key is essential for the hashing process.
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class JwtSigner {
public static void main(String[] args) throws Exception {
String encodedHeader = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"; // {"alg":"HS256","typ":"JWT"}
String encodedPayload = "eyJpZCI6MSwicm9sZSI6InVzZXIifQ"; // {"id":1,"role":"user"}
String secret = "coddykit-secret-lesson-key-1234567890";
String dataToSign = encodedHeader + "." + encodedPayload;
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256");
hmacSha256.init(secretKey);
byte[] signatureBytes = hmacSha256.doFinal(dataToSign.getBytes("UTF-8"));
String encodedSignature = Base64.getUrlEncoder().withoutPadding().encodeToString(signatureBytes);
System.out.println("Data to Sign: " + dataToSign);
System.out.println("Generated Signature: " + encodedSignature);
System.out.println("Full JWT: " + dataToSign + "." + encodedSignature);
}
}Verifying a JWT's Signature
Verification is the reverse process of signing. When you receive a JWT, you need to ensure its signature is valid.
- Separate the received JWT into its three parts: header, payload, and signature.
- Reconstruct the "data to sign" string:
encodedHeader + "." + encodedPayload. - Using the same secret key and algorithm, calculate a new signature from this data.
- Compare your newly calculated signature with the signature provided in the JWT.
If they match, the token is valid and untampered! If not, it's invalid.
Secure Key Management
The security of your JWTs critically depends on how well you manage your signing keys. A compromised key invalidates all your security efforts!
- Confidentiality: Keep secret keys private. Never hardcode them in client-side code.
- Rotation: Regularly change your keys to limit the impact of a potential compromise.
- Strength: Use strong, random, and sufficiently long keys.
- Store keys in secure environments, like environment variables or dedicated key management services.
Code: Verifying HS256 Signature
This example demonstrates how to verify a JWT's signature. We use the same secret key to recalculate the signature and compare it against the one in the token.
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class JwtVerifier {
public static void main(String[] args) throws Exception {
String jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6InVzZXIifQ.qS6pQ_6_q-P_5_o-O_6_n-N_7_m-M_8_l-L_9_k-K_0_j-J_1_i-I_2_h-H_3_g-G_4_f-F_5_e-E_6_d-D_7_c-C_8_b-B_9_a-A";
String secret = "coddykit-secret-lesson-key-1234567890";
String[] parts = jwt.split("\\.");
String encodedHeader = parts[0];
String encodedPayload = parts[1];
String receivedSignature = parts[2];
String dataToSign = encodedHeader + "." + encodedPayload;
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256");
hmacSha256.init(secretKey);
byte[] calculatedSignatureBytes = hmacSha256.doFinal(dataToSign.getBytes("UTF-8"));
String calculatedSignature = Base64.getUrlEncoder().withoutPadding().encodeToString(calculatedSignatureBytes);
if (calculatedSignature.equals(receivedSignature)) {
System.out.println("Signature is VALID!");
} else {
System.out.println("Signature is INVALID!");
System.out.println("Received: " + receivedSignature);
System.out.println("Calculated: " + calculatedSignature);
}
}
}Symmetric vs. Asymmetric Signing
While HS256 (HMAC SHA-256) uses a shared secret, RS256 (RSA SHA-256) and ES256 (ECDSA SHA-256) use key pairs.
- Symmetric (e.g., HS256): Same key for signing and verifying. Best for single-service applications or when the verifier is also the issuer.
- Asymmetric (e.g., RS256, ES256): Private key for signing, public key for verifying. Ideal for distributed systems where multiple services need to verify tokens issued by a central authority. The public key can be shared widely without compromising security.
Quick Check: JWT Security
You've learned about JWT signing and verification. Let's test your understanding.
Recap: Secure JWTs
Great job! We've demystified how JWTs are secured through signing and verification.
- Signing ensures a JWT's integrity and authenticity using a cryptographic algorithm and a secret key.
- HS256 (HMAC SHA-256) is a symmetric algorithm using a single shared secret.
- Verification involves recalculating the signature and comparing it to the received one.
- Secure key management is paramount for JWT security.
- Asymmetric algorithms like RS256 use key pairs for distributed verification.
Next up, we'll see how to integrate JWTs with Spring Security!
자주 묻는 질문
“JWT 서명 및 검증” 강의는 무료인가요?
네 — “JWT 서명 및 검증” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Spring Security 6 & JWT Authentication 강의 전체를 잠금 해제할 수 있습니다. Spring Security 6 & JWT Authentication 강의에는 총 4개의 강의가 포함되어 있습니다.
“JWT 서명 및 검증”에서 뭘 배우나요?
JWT 서명에 사용되는 암호학적 원리와 토큰의 무결성 및 진위를 검증하는 방법을 배웁니다. 브라우저에서 직접 실행하는 실습 코드로 Spring Security 6 & JWT Authentication을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Spring Security 6 & JWT Authentication을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Spring Security 6 & JWT Authentication은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“JWT 서명 및 검증” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Spring Security 6 & JWT Authentication 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Spring Security 6 & JWT Authentication 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- JSON 웹 토큰 이해하기
- JWT 구조 및 클레임
- JWT 서명 및 검증
- JWT 만료 및 검증 규칙