Skip to content

Commit 28d6190

Browse files
authored
custom HS256 사용으로 jwt secret 길이 제한 우회 (#381)
1 parent 0d3650b commit 28d6190

1 file changed

Lines changed: 29 additions & 3 deletions

File tree

api/src/main/kotlin/middleware/ApiKeyMiddleware.kt

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.wafflestudio.snutt.middleware
33
import com.wafflestudio.snutt.common.exception.WrongApiKeyException
44
import com.wafflestudio.snutt.handler.RequestContext
55
import io.jsonwebtoken.Jwts
6+
import io.jsonwebtoken.security.MacAlgorithm
67
import org.springframework.beans.factory.annotation.Value
78
import org.springframework.stereotype.Component
89
import org.springframework.web.reactive.function.server.ServerRequest
@@ -12,8 +13,33 @@ import javax.crypto.spec.SecretKeySpec
1213
class ApiKeyMiddleware(
1314
@Value("\${snutt.secret-key}") private val secretKey: String,
1415
) : Middleware {
15-
private val keySpec = SecretKeySpec(secretKey.toByteArray(), "HmacSHA256")
16-
private val jwtParser = Jwts.parser().verifyWith(keySpec).build()
16+
companion object {
17+
const val API_KEY_HEADER = "x-access-apikey"
18+
const val HMAC_SHA256_ALGORITHM_ID = "HS256"
19+
const val HMAC_SHA256_JCA_NAME = "HmacSHA256"
20+
const val DEFAULT_MAC_ALGORITHM_CLASS = "io.jsonwebtoken.impl.security.DefaultMacAlgorithm"
21+
}
22+
23+
private val keySpec = SecretKeySpec(secretKey.toByteArray(), HMAC_SHA256_JCA_NAME)
24+
25+
private val customHS256 =
26+
run {
27+
val minKeyBitLength = 80
28+
Class
29+
.forName(DEFAULT_MAC_ALGORITHM_CLASS)
30+
.getDeclaredConstructor(String::class.java, String::class.java, Int::class.java)
31+
.apply { isAccessible = true }
32+
.newInstance(HMAC_SHA256_ALGORITHM_ID, HMAC_SHA256_JCA_NAME, minKeyBitLength) as MacAlgorithm
33+
}
34+
private val jwtParser =
35+
Jwts
36+
.parser()
37+
.verifyWith(keySpec)
38+
.sig()
39+
.remove(Jwts.SIG.HS256)
40+
.add(customHS256)
41+
.and()
42+
.build()
1743
private val stringToKeyVersionMap =
1844
mapOf(
1945
"ios" to "0",
@@ -27,7 +53,7 @@ class ApiKeyMiddleware(
2753
context: RequestContext,
2854
): RequestContext =
2955
runCatching {
30-
val apiKey = requireNotNull(req.headers().firstHeader("x-access-apikey"))
56+
val apiKey = requireNotNull(req.headers().firstHeader(API_KEY_HEADER))
3157
val claims = jwtParser.parseSignedClaims(apiKey).payload
3258

3359
val string = claims["string"]!!.toString()

0 commit comments

Comments
 (0)