Avatar
1
Shi Shi Beginner
Shi Shi Beginner
jwt in java
em chào mọi người, mọi người cho e hỏi e dùng thuật ES256 để gen token

nhưng khi có token để verify ví dụ như này

public key :

MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE02Ar8685UapqDlOT8TneixaeR2Uu0tRu0R8WTG5ATA7j3Nk9x6poNYiH/Ez6jhwQg/ocioHsjzOOStUeSN8aIg== 
và token :

eyJhbGciOiJFUzI1NiJ9.eyJzdWIiOiJ0ZXN0LW5vYyIsImF1dGgiOiJCSV9FWFBPUlQiLCJlbWFpbCI6ImFiYy5jb20udm4iLCJmdWxsX25hbWUiOiJCVSBOT0MiLCJST0xFX0pXVCI6IkJJX0VYUE9SVCIsIk1OVl9KV1QiOiJ0ZXN0LW5vY19ub2MiLCJleHAiOjk5OTk5OTk5OTk5OTk5fQ.xdtY5Rbay7I5733gBOzSoPFrADCwqE7PhuNGd0zdkyB81wbGunFny2CjagQfgVr_kg0RviUmusjGmjiVk3zB_Q

thì khi verify tại sao e thêm 1 ký tự bất kỳ vào cuối token nó vẫn verify thành công ạ, nhưng thêm đến ký tự thứ 2 vào cuối hoặc chỉ thêm ký tự . vào cuối thì verify thất bại, nếu theo nguyên tắc e làm sai khác token đi so với bán đầu nó phải verify thất bại luôn chứ ạ, mong mọi người giải đáp giúp e, e cảm ơn.

public class GenToken {

    public static void main(String[] args) throws Exception {
        KeyPair keyPair = generateECKeyPair();
        String publicKeyBase64 = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
        String privateKeyBase64 = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());
        String jwtToken = createJwtToken(publicKeyBase64, privateKeyBase64);
    }

    private static KeyPair generateECKeyPair() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
        ECGenParameterSpec ecGenParameterSpec = new ECGenParameterSpec("secp256r1");
        keyPairGenerator.initialize(ecGenParameterSpec);
        return keyPairGenerator.generateKeyPair();
    }

    private static String createJwtToken(String publicKeyBase64, String privateKeyBase64) {
        Date expirationDate = new Date(99999999999999999L); 
        return Jwts.builder()
                .setSubject("test-noc")
                .claim("auth", "EXPORT")
                .claim("email", "abc.com.vn")
                .claim("full_name", "BU")
                .claim("ROLE_JWT", "EXPORT")
                .claim("MNV_JWT", "test-manv")
                .setExpiration(expirationDate)
                .signWith(
                        SignatureAlgorithm.ES256,
                        getPrivateKey(privateKeyBase64)
                )
                .compact();
    }

    private static PrivateKey getPrivateKey(String privateKeyBase64) {
        try {
            byte[] keyBytes = Base64.getDecoder().decode(privateKeyBase64);
            KeyFactory keyFactory = KeyFactory.getInstance("EC");
            return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
        } catch (Exception e) {
            throw new RuntimeException("Error loading private key", e);
        }
    }

còn đây là class verify token của e

public class JwtProcess {

    SignatureAlgorithm algorithm;

    private  PublicKey getPublicKey(String publicKeyBase64) throws Exception {

        algorithm = SignatureAlgorithm.ES256;
        byte[] decoded = Base64.getDecoder().decode(publicKeyBase64);
        X509EncodedKeySpec spec = new X509EncodedKeySpec(decoded);
        KeyFactory kf = KeyFactory.getInstance(algorithm.isRsa() ? "RSA" : "EC");
        return kf.generatePublic(spec);
    }

    public boolean verifyToken(String token, String publicKeyBase64) {
        try {
            PublicKey publicKey = getPublicKey(publicKeyBase64);
            Jwts.parserBuilder().setSigningKey(publicKey).build().parseClaimsJws(token);
            return true;

        } catch (Exception e) {
            e.printStackTrace();
            throw new ObjectException(" Could not verify JWT token integrity! ");
        }
    }

    public JwtClaims decodeToken(String token, String publicKey) throws Exception {
            Claims claims = Jwts.parser()
                    .setSigningKey(getPublicKey(publicKey))
                    .parseClaimsJws(String.valueOf(token)).getBody();
            return new JwtClaims(
                    claims.getSubject(),
                    claims.get("auth").toString(),
                    claims.get("email").toString(),
                    claims.get("full_name").toString(),
                    claims.get("ROLE_JWT").toString(),
                    claims.get("MNV_JWT").toString(),
                    claims.get("exp").toString()
            );
    }

}
  • Answer
Remain: 5
2 Answers
Avatar
tvd12 Beginner
tvd12 Beginner
Em đang dùng thư viện nào nhỉ?
  • 0
  • Reply
e dùng thư viện import io.jsonwebtoken.Jwts; anh ạ  –  Shi Shi 1712496981000
em dùng
import io.jsonwebtoken.Jwts;


  public boolean verifyToken(String token, String publicKeyBase64) {
        try {
            PublicKey publicKey = getPublicKey(publicKeyBase64);
            Jwts.parserBuilder().setSigningKey(publicKey).build().parseClaimsJws(token);
            return true;

        } catch (Exception e) {
            e.printStackTrace();
            throw new ObjectException(" Could not verify JWT token integrity! ");
        }
    }
 –  Shi Shi 1712497042000
Avatar
tvd12 Beginner
tvd12 Beginner
Anh dùng bản mới, anh thêm 1 kí tự bất kỳ thì nó báo lỗi luôn em ạ:
o.jsonwebtoken.security.SignatureException: Unable to verify Elliptic Curve signature using provided ECPublicKey: Provided signature is 520 bits (65 bytes) but ES256 signatures must be exactly 512 bits (64 bytes) per [RFC 7518, Section 3.4 (validation)](https://www.rfc-editor.org/rfc/rfc7518.html#section-3.4).
	at io.jsonwebtoken.impl.security.EcSignatureAlgorithm$2.apply(EcSignatureAlgorithm.java:234)

Đây là dependencies:

dependencies {
    implementation 'io.jsonwebtoken:jjwt-api:0.12.5'
    implementation 'io.jsonwebtoken:jjwt-impl:0.12.5'
    implementation 'io.jsonwebtoken:jjwt-gson:0.12.5'
}

Còn đây là mã nguồn:

import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

import io.jsonwebtoken.Jwts;

public class JwtVerifyExample {

    private static final String publicKeyBase64 = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE02Ar8685UapqDlOT8TneixaeR2Uu0tRu0R8WTG5ATA7j3Nk9x6poNYiH/Ez6jhwQg/ocioHsjzOOStUeSN8aIg==";
    private static final String token = "eyJhbGciOiJFUzI1NiJ9.eyJzdWIiOiJ0ZXN0LW5vYyIsImF1dGgiOiJCSV9FWFBPUlQiLCJlbWFpbCI6ImFiYy5jb20udm4iLCJmdWxsX25hbWUiOiJCVSBOT0MiLCJST0xFX0pXVCI6IkJJX0VYUE9SVCIsIk1OVl9KV1QiOiJ0ZXN0LW5vY19ub2MiLCJleHAiOjk5OTk5OTk5OTk5OTk5fQ.xdtY5Rbay7I5733gBOzSoPFrADCwqE7PhuNGd0zdkyB81wbGunFny2CjagQfgVr_kg0RviUmusjGmjiVk3zB_Q";

    public static void main(String[] args) {
        try {
            PublicKey publicKey = getPublicKey();
            Jwts.parser()
                .verifyWith(publicKey)
                .build()
                .parseSignedClaims(token);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static PublicKey getPublicKey() throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(JwtVerifyExample.publicKeyBase64);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("EC"); // Or whatever algorithm your key is using
        return keyFactory.generatePublic(keySpec);
    }
}

Em thử xem sao nhé.

  • 0
  • Reply