2016-08-14 5 views
2

JJWT 라이브러리를 사용하여 JWT 토큰을 생성하고 있습니다. 다음과 같이 토큰을 생성합니다. 내 비밀 키로 더미 값을 사용하고 있습니다.JJWT 생성 된 토큰의 서명이 올바르지 않습니다.

우리는 토큰이 성공적으로 디코딩 할 수 있지만 jwt.security.key=security-key

@Value("${jwt.security.key}") 
    private String key; 

    @Value("${ws.issuer}") 
    private String issuer; 

    static final long ONE_MINUTE_IN_MILLIS=60000; 

    static final long TOKEN_DURATION_IN_MIN=30L; 

    private SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; 

    @Override 
    public String issueToken(String userName) { 

     long nowMillis = System.currentTimeMillis(); 
     long expMillis = nowMillis + (ONE_MINUTE_IN_MILLIS * TOKEN_DURATION_IN_MIN); 

     return Jwts 
       .builder() 
       .setId("01") 
       .setIssuedAt(new Date(nowMillis)) 
       .setHeaderParam("typ","JWT") 
       .setSubject(userName) 
       .setIssuer(issuer) 
       .setExpiration(new Date(expMillis)) 
       .signWith(signatureAlgorithm, key).compact(); 

    } 

있다고 가정 할 수 있습니다. jwt.io 디버거에서 서명 할 때마다 잘못된 서명이 항상 발생합니다. 어떤 볼 수 here.

+0

"디코딩"탭의 "서명 확인"에서 토큰을 인코딩하는 데 사용 된 암호를 설정해 보았습니까? 그렇게해야합니다. 비밀을 알아야하는 JWT를 확인하려면 클라이언트 만 본문이 올바른 것으로 가정해야합니다. –

+0

나는 validator가 jwt.io에 의해 손상되었다고 생각한다 (아직도, 분명히). 유효성 검사를 생략하고 내 응용 프로그램에서 그렇게하면 내 비밀 키가 올바르게 유효 함이 입증되었습니다. –

답변

1

security-key은 유효한 Base64 인코딩 문자열이 아닙니다.

또한
/** 
* Signs the constructed JWT using the specified algorithm with the specified key, producing a JWS. 
* 
* <p>This is a convenience method: the string argument is first BASE64-decoded to a byte array and this resulting 
* byte array is used to invoke {@link #signWith(SignatureAlgorithm, byte[])}.</p> 
* 
* @param alg     the JWS algorithm to use to digitally sign the JWT, thereby producing a JWS. 
* @param base64EncodedSecretKey the BASE64-encoded algorithm-specific signing key to use to digitally sign the 
*        JWT. 
* @return the builder for method chaining. 
*/ 
JwtBuilder signWith(SignatureAlgorithm alg, String base64EncodedSecretKey); 

, 왜 jwt.io가 파손 될 수 있음을 고려하지 : JavaDoc을하고 signWith(SignatureAlgorithm, String) 메소드의 인수 이름을 읽어? 그것은 권위있는 jwt 도구가 아닙니다.

마지막으로 평문 문자열이나 임의의 문자열을 서명 키로 사용해서는 안됩니다. 디지털 서명은 항상 바이트 배열로 계산됩니다. 암호화를 안전하게하려면 항상 사용하는 서명 알고리즘에 충분한 길이의 보안 임의 바이트 배열을 사용해야합니다.

충분히 길고 강한 키를 생성하려면 JJWT의 MacProvider.generateKey 메소드를보십시오.

jwt.io 사이트는이 사실을 분명히하지 않으므로 오해의 소지가 있습니다. 이전 문자열을 서명 키로 사용할 수 있음을 의미합니다. 기술적으로는 일 수 있지만 분명히해서는 안됩니다. 문자열로 표현할 필요가 있다면 Base64로 인코딩 된 보안 임의 바이트 배열을 항상 사용해야합니다. 이것이 String을 키로 받아들이는 JJWT의 메소드가 Base64로 인코딩되었다고 가정하는 이유입니다. 그렇지 않으면 유효하지 않거나 형식이 잘못된 키를 사용하고 있기 때문입니다.

+0

문서를 보지 못해서 나쁘다. MacProvider.generateKey를 사용하여 키를 생성했으면 Base64를 사용하여 인코딩해야합니까? 그 다음에 서명해서 보내십시오. – KyelJmD

+0

'TextCodec.BASE64.encode (key.getEncoded());'참고 : 결과 Base64로 인코딩 된 문자열은 JJWT로 전달할 수 있지만 암호화되지 않은 것으로 간주됩니다 (단지 바이트에서 문자열로 변환 됨). 저장하기 전에 문자열을 안전하게 유지하거나 암호화해야합니다. –

+0

마지막 질문 하나, 귀하의 의견을 명확히 할 수 있도록 요지를 만들었습니다. 내가 변수 base64EncodeKey, 나는 /를 암호화 안전하게 보관해야 준 요지를 바탕으로 https://gist.github.com/kyeljmd/a68567680787e0d0eeef137479cd85aa ? 이 JWT 수신자는 토큰이 유효한지 어떻게 확인합니까? – KyelJmD