{"record":{"id":"7f2fbd0d8a7ed801","repo":"jwtk/jjwt","slug":"the-none-algorithm-cannot-be-used-to-verify-sign","errorCode":null,"errorMessage":"The 'none' algorithm cannot be used to verify signatures.","messagePattern":"The 'none' algorithm cannot be used to verify signatures\\.","errorType":"exception","errorClass":"SignatureException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/security/NoneSignatureAlgorithm.java","lineNumber":48,"sourceCode":"\n    static final SecureDigestAlgorithm<Key, Key> INSTANCE = new NoneSignatureAlgorithm();\n\n    private NoneSignatureAlgorithm() {\n    }\n\n    @Override\n    public String getId() {\n        return ID;\n    }\n\n    @Override\n    public byte[] digest(SecureRequest<InputStream, Key> request) throws SecurityException {\n        throw new SignatureException(\"The 'none' algorithm cannot be used to create signatures.\");\n    }\n\n    @Override\n    public boolean verify(VerifySecureDigestRequest<Key> request) throws SignatureException {\n        throw new SignatureException(\"The 'none' algorithm cannot be used to verify signatures.\");\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        return this == obj ||\n                (obj instanceof SecureDigestAlgorithm &&\n                        ID.equalsIgnoreCase(((SecureDigestAlgorithm<?, ?>) obj).getId()));\n    }\n\n    @Override\n    public int hashCode() {\n        return getId().hashCode();\n    }\n\n    @Override\n    public String toString() {\n        return ID;\n    }","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/security/NoneSignatureAlgorithm.java#L30-L66","documentation":"The 'none' (unsecured) JWS algorithm rejects all verification attempts in JJWT. verify() always throws SignatureException because accepting 'alg: none' tokens is a classic JWT vulnerability; verification with no signature cannot establish authenticity.","triggerScenarios":"Calling Jwts.parser().verifyWith(Jwts.SIG.none) or verifying a token whose header declares alg=none via an algorithm configured as NoneSignatureAlgorithm.","commonSituations":"Trying to parse unsigned tokens produced by another system; security testing of alg=none attacks; migrating legacy tokens that were created without a signature.","solutions":["Re-issue the tokens with a real algorithm (e.g. HS256) and verify with the corresponding key.","If unsigned tokens must be consumed, parse the payload manually rather than using JJWT's verified parser.","Never configure a parser to accept 'none' for production tokens."],"exampleFix":"// before\nJws<Claims> jws = Jwts.parser().verifyWith(Jwts.SIG.none).build().parseSignedClaims(token);\n// after\nJws<Claims> jws = Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token);","handlingStrategy":"try-catch","validationCode":"if (headerAlg != null && \"none\".equals(headerAlg)) {\n    throw new SecurityException(\"Rejecting unsecured token (alg=none)\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    Jws<Claims> jws = Jwts.parser().verifyWith(key).build().parseSignedClaims(token);\n} catch (SignatureException e) {\n    // includes alg=none verification refusal\n    throw new AuthenticationException(\"Invalid token signature\", e);\n}","preventionTips":["Never accept alg=none tokens in production","Always pin the expected algorithm in the parser","Migrate legacy unsigned tokens to signed ones"],"tags":["jwt","security","signature"],"backgroundTag":"unsupported-operation","analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}