Notice
Recent Posts
Recent Comments
Link
개발 무지렁이
[Spring Boot] 인코딩 및 암호화 알고리즘을 통해 비밀키 생성, 이를 사용해 Jwt의 헤더와 페이로드를 서명 (무결성 보장) 본문
Backend/스프링부트
[Spring Boot] 인코딩 및 암호화 알고리즘을 통해 비밀키 생성, 이를 사용해 Jwt의 헤더와 페이로드를 서명 (무결성 보장)
Gaejirang-e 2023. 9. 27. 16:13
𐂂 JwtConfig
📜 jwt 비밀키 생성 객체 Bean등록.java
@Configuration
public class JwtConfig {
@Value("${custom.jwt.secretKey}")
private String secretKeyPlain;
@Bean
public SecretKey jwtSecretKey() {
String keyBase64Encoded = Base64.getEncoder().encodeToString(secretKeyPlain.getBytes());
return Keys.hmacShaKeyFor(keyBase64Encoded.getBytes());
}
}
🦉 @Value("${ }")
: 외부 설정파일에서(properties, yml..)에서 값을 가져와 해당 클래스의 필드에 주입하는데 사용된다.
: 외부 설정파일에서(properties, yml..)에서 값을 가져와 해당 클래스의 필드에 주입하는데 사용된다.
🦉 Base64 (3Bytes[24bits] 이진데이터 -> 4개 Base64 문자[24bits / 1문자, 6bits]로 변환)
[ 알파벳 대/소문자, 숫자, +, / ]
: 이진데이터를 텍스트 형식으로 인코딩하거나, 반대로 디코딩하는데 사용되는 인코딩 체계 중 하나이다.
🍟 이메일 첨부파일 (텍스트 형식의 데이터만 지원)
🍟 웹 이미지 (이미지 파일을 데이터 url로 인코딩하여 웹페이지에 표시)
🍟 암호화 (일부 암호화 알고리즘에서 Base64 인코딩을 사용해, 암호화된 데이터를 텍스트로 표현)
[ 알파벳 대/소문자, 숫자, +, / ]
: 이진데이터를 텍스트 형식으로 인코딩하거나, 반대로 디코딩하는데 사용되는 인코딩 체계 중 하나이다.
🍟 이메일 첨부파일 (텍스트 형식의 데이터만 지원)
🍟 웹 이미지 (이미지 파일을 데이터 url로 인코딩하여 웹페이지에 표시)
🍟 암호화 (일부 암호화 알고리즘에서 Base64 인코딩을 사용해, 암호화된 데이터를 텍스트로 표현)
🐘 implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
🐘 runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
🐘 runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
🦉 Keys 클래스
: JWT의 서명(Signature, 비밀키) 생성 및 검증을 위한 키(Material, 공개키)를 관리하는 데 사용된다.
⚠️ 서명(Signature)을 생성함으로써 JWT🧩 무결성을 보장, 위조 방지한다.
🗝️ Keys.hmacShaKeyFor(keyBasedEncoded.getBytes());
HMAC-SHA(Hash-based Message Authentication Code - Secure Hash Algorithm)라는 알고리즘에 기반한
JWT 서명(비밀키, SecretKey)을 생성
❓javax.crypto.SecretKey
: Java에서 비밀키를 나타내기 위해 사용되는 인터페이스
: JWT의 서명(Signature, 비밀키) 생성 및 검증을 위한 키(Material, 공개키)를 관리하는 데 사용된다.
⚠️ 서명(Signature)을 생성함으로써 JWT🧩 무결성을 보장, 위조 방지한다.
🗝️ Keys.hmacShaKeyFor(keyBasedEncoded.getBytes());
HMAC-SHA(Hash-based Message Authentication Code - Secure Hash Algorithm)라는 알고리즘에 기반한
JWT 서명(비밀키, SecretKey)을 생성
❓javax.crypto.SecretKey
: Java에서 비밀키를 나타내기 위해 사용되는 인터페이스
𐁍 JwtProvider
📜 Jwt의 관련정보를 다루는 JwtProvider.java
@Component
@RequiredArgsConstructor
public class JwtProvider {
private final SecretKey jwtSecretKey
private SecretKey getSecretKey() {
return jwtSecretKey;
}
public String generateAccessToken(Map<String, Object> claims, int seconds) {
long now = new Date().getTime();
Date accessTokenExpiresIn = new Date(now + 1000L * seconds);
return Jwts.builder()
.claim("body", Util.json.toStr(claims))
.setExpiration(accessTokenExpiresIn) //유효기간 설정
.signWith(getSecretKey(), SignatureAlgorithm.HS512) //서명
.compact();
}
}
📜 Util.java
public class Util {
private static ObjectMapper getObjectMapper() {
return (ObjectMapper) AppConfig.getContext().getBean("objectMapper");
}
public static class json {
public static Object toStr(Map<String, Object> map) {
try {
return getObjectMapper().writeValueAsString(map);
} catch(JsonProcessingException e) {
return null;
}
}
public static Map<String, Object> toMap(String jsonStr) {
try {
return getObjectMapper().realValue(jsonStr, LinkedHashMap.class);
} catch(JsonProcessingException e) {
return null;
}
}
}
}
📜 AppApplication.java
@SpringBootApplication
public class AppApplication {
public static void main(String[] args) {
SpringApplication.run(AppApplication.class, args);
}
@Bean
public ObjectMapper objectMapper() {
return new ObjectMapper();
}
}
📜 AppConfig.java
@Configuration
public class AppConfig {
@Getter
private static ApplicationContext context;
@Autowired
public void setContext(ApplicationContext context) {
AppConfig.context = context;
}
}
🦉 클레임(claim)
: Jwt가 정보를 표현하는데 사용하는 용어를 말한다.
: Jwt가 정보를 표현하는데 사용하는 용어를 말한다.
🦉 왜 getObjectMapper()를 통해서 ObjectMapper객체를 가져올까?
* 그냥 private ObjectMapper objectMapper 필드에 @Autowired를 붙여서 사용하면 되는거 아닌가? *
위의 코드를 보면 objectMapper를 사용하는 곳은 static 메서드 안이다.
static 메서드에서 사용되려면 static 필드여야하는데, static을 붙이면 @Autowired를 사용할 수 없다. *
따라서 위의 코드와 같이 ApplicationContext를 가져와 등록된 Bean중
'objectMapper'라는 이름의 Bean을 가져온다.
이렇게 Bean을 가져올 수 있는 것은
진입점클래스(entry point class)에서 ObjectMapper 객체를 Bean으로 등록했기 때문이다.
(@SpringBootApplication 안에 @Configuration이 있어 해당 클래스를 살펴 @Bean이 있으면 Bean으로 등록한다.)
❓ objectMapper
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.14.2'
- JSON 직렬화 (Collections ➡️ JSON)
- JSON 역직렬화 (JSON ➡️ Collections)
❓ ApplicationContext: 스프링 애플리케이션의 설정정보를 읽고 객체를 관리하는 역할을 한다.
* 그냥 private ObjectMapper objectMapper 필드에 @Autowired를 붙여서 사용하면 되는거 아닌가? *
위의 코드를 보면 objectMapper를 사용하는 곳은 static 메서드 안이다.
static 메서드에서 사용되려면 static 필드여야하는데, static을 붙이면 @Autowired를 사용할 수 없다. *
따라서 위의 코드와 같이 ApplicationContext를 가져와 등록된 Bean중
'objectMapper'라는 이름의 Bean을 가져온다.
이렇게 Bean을 가져올 수 있는 것은
진입점클래스(entry point class)에서 ObjectMapper 객체를 Bean으로 등록했기 때문이다.
(@SpringBootApplication 안에 @Configuration이 있어 해당 클래스를 살펴 @Bean이 있으면 Bean으로 등록한다.)
❓ objectMapper
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.14.2'
- JSON 직렬화 (Collections ➡️ JSON)
- JSON 역직렬화 (JSON ➡️ Collections)
❓ ApplicationContext: 스프링 애플리케이션의 설정정보를 읽고 객체를 관리하는 역할을 한다.
'Backend > 스프링부트' 카테고리의 다른 글
[Spring Boot] 카카오페이(KakaoPay) 단건 결제 기능 구현, 결제 준비 API 및 결제 승인 API (0) | 2023.10.03 |
---|---|
[Spring Boot] 공통 관심사항을 모아놓고, 원하는 곳에 적용하는 AOP(Aspect Oriented Programming)와 이를 가능하게 하는 프록시 객체(가짜객체) (0) | 2023.09.27 |
[Spring Boot] 컨트롤러에서 정적/동적 콘텐츠를 클라이언트에 넘겨주는 방식 (0) | 2023.09.08 |
[Spring Boot] Pageable 인터페이스와 페이징(Paging) 처리 (0) | 2023.06.04 |
[Spring Boot] 설정정보(개발용, 배포용, 테스트용) (0) | 2023.01.12 |
Comments