Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

[Bug] WeakKeyException ao fazer o post

Bom dia!

Quanto faço o post pra trazer o token, apresenta o erro 403 com a descrição:

io.jsonwebtoken.security.WeakKeyException: The signing key's size is 56 bits which is not secure enough for the HS512 algorithm.  The JWT JWA Specification (RFC 7518, Section 3.2) states that keys used with HS512 MUST have a size >= 512 bits (the key size must be greater than or equal to the hash output size).  Consider using the io.jsonwebtoken.security.Keys class's 'secretKeyFor(SignatureAlgorithm.HS512)' method to create a key guaranteed to be secure enough for HS512.  See https://tools.ietf.org/html/rfc7518#section-3.2 for more information.
    at io.jsonwebtoken.SignatureAlgorithm.assertValid(SignatureAlgorithm.java:387) ~[jjwt-api-0.11.5.jar:0.11.5]
    at io.jsonwebtoken.SignatureAlgorithm.assertValidSigningKey(SignatureAlgorithm.java:315) ~[jjwt-api-0.11.5.jar:0.11.5]
    at io.jsonwebtoken.impl.DefaultJwtBuilder.signWith(DefaultJwtBuilder.java:112) ~[jjwt-impl-0.11.5.jar:0.11.5]
    at io.jsonwebtoken.impl.DefaultJwtBuilder.signWith(DefaultJwtBuilder.java:125) ~[jjwt-impl-0.11.5.jar:0.11.5]
    at br.com.alura.forum.config.JWTUtil.generateToken(JWTUtil.kt:23) ~[classes/:na]
    at br.com.alura.forum.security.JWTLoginFilter.successfulAuthentication(JWTLoginFilter.kt:33) ~[classes/:na]

Algumas métodos estão depracted (acredito que o curso esteja um pouco desatualizado).

Segue as classes JWTLoginFilter e JWTUtil:

class JWTLoginFilter(
    private val authManager: AuthenticationManager,
    private val jwtUtil: JWTUtil
) : UsernamePasswordAuthenticationFilter () {

    override fun attemptAuthentication(request: HttpServletRequest?, response: HttpServletResponse?): Authentication {
        val(username, password) = ObjectMapper().readValue(request?.inputStream, Credentials::class.java)
        val token = UsernamePasswordAuthenticationToken(username, password)
        return authManager.authenticate(token)
    }

    override fun successfulAuthentication(
        request: HttpServletRequest?,
        response: HttpServletResponse?,
        chain: FilterChain?,
        authResult: Authentication?
    ) {
        val username = (authResult?.principal as UserDetails).username
        val token = jwtUtil.generateToken(username)
        response?.addHeader("Authorization", "Bearer $token")
    }
}
@Component
class JWTUtil {
    private val expiration: Long = 60000

    @Value("\${jwt.secret}")
    private lateinit var secret: String

    fun generateToken(username: String): String? {
        return Jwts.builder()
            .setSubject(username)
            .setExpiration(Date(System.currentTimeMillis() + expiration))
            .signWith(SignatureAlgorithm.HS512, secret.toByteArray())
            .compact()
    }

    fun isValid(jwt: String?): Boolean {
        return try {
            Jwts.parser().setSigningKey(secret.toByteArray()).parseClaimsJws(jwt)
            true
        } catch (e: IllegalArgumentException) {
            false
        }
    }

    fun getAuthentication(jwt: String?): Authentication {
        val username = Jwts.parser().setSigningKey(secret.toByteArray()).parseClaimsJws(jwt).body.subject
        return UsernamePasswordAuthenticationToken(username, null)
    }
}
2 respostas
solução!

Olá André, tudo bem? O erro "The signing key's size is 56 bits which is not secure enough for the HS512 algorithm" indica que a chave usada para assinar o token JWT é muito curta (56 bits) para o algoritmo HS512, que requer uma chave com tamanho mínimo de 512 bits. A solução recomendada pelo erro é usar o método secretKeyFor da classe Keys para gerar uma chave segura para o algoritmo HS512. Exemplo:

import io.jsonwebtoken.security.Keys

...

private val key = Keys.secretKeyFor(SignatureAlgorithm.HS512)

...

fun generateToken(username: String): String? {
    return Jwts.builder()
        .setSubject(username)
        .setExpiration(Date(System.currentTimeMillis() + expiration))
        .signWith(key)
        .compact()
}

...

fun isValid(jwt: String?): Boolean {
    return try {
        Jwts.parser().setSigningKey(key).parseClaimsJws(jwt)
        true
    } catch (e: IllegalArgumentException) {
        false
    }
}

fun getAuthentication(jwt: String?): Authentication {
    val username = Jwts.parser().setSigningKey(key).parseClaimsJws(jwt).body.subject
    return UsernamePasswordAuthenticationToken(username, null)
}

Obrigado @Otávio Prado!

Além disso, tive que adicionar essas dependências no pom.xml.

<dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt-impl</artifactId>
        <version>0.11.5</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt-jackson</artifactId>
        <version>0.11.1</version>
        <scope>runtime</scope>
    </dependency>