{"record":{"id":"3018ee6587179f8b","repo":"jwtk/jjwt","slug":"the-keytype-signing-key-s-algorithm-name","errorCode":null,"errorMessage":"The ${keyType(signing)} key's algorithm '${name}' does not equal a valid HmacSHA* algorithm name or PKCS12 OID and cannot be used with ${getId()}.","messagePattern":"The (.+?) key's algorithm '(.+?)' does not equal a valid HmacSHA\\* algorithm name or PKCS12 OID and cannot be used with (.+?)\\.","errorType":"validation","errorClass":"InvalidKeyException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/security/DefaultMacAlgorithm.java","lineNumber":144,"sourceCode":"    public SecretKeyBuilder key() {\n        return new DefaultSecretKeyBuilder(getJcaName(), getKeyBitLength());\n    }\n\n    private void assertAlgorithmName(SecretKey key, boolean signing) {\n\n        String name = key.getAlgorithm();\n        if (!Strings.hasText(name)) {\n            String msg = \"The \" + keyType(signing) + \" key's algorithm cannot be null or empty.\";\n            throw new InvalidKeyException(msg);\n        }\n\n        // We can ignore key name assertions for generic secrets, because HSM module key algorithm names\n        // don't always align with JCA standard algorithm names\n        boolean generic = KeysBridge.isGenericSecret(key);\n\n        //assert key's jca name is valid if it's a JWA standard algorithm:\n        if (!generic && isJwaStandard() && !isJwaStandardJcaName(name)) {\n            throw new InvalidKeyException(\"The \" + keyType(signing) + \" key's algorithm '\" + name +\n                    \"' does not equal a valid HmacSHA* algorithm name or PKCS12 OID and cannot be used with \" +\n                    getId() + \".\");\n        }\n    }\n\n    @Override\n    protected void validateKey(Key k, boolean signing) {\n\n        final String keyType = keyType(signing);\n        if (k == null) {\n            throw new IllegalArgumentException(\"MAC \" + keyType + \" key cannot be null.\");\n        }\n\n        if (!(k instanceof SecretKey)) {\n            String msg = \"MAC \" + keyType + \" keys must be SecretKey instances.  Specified key is of type \" +\n                    k.getClass().getName();\n            throw new InvalidKeyException(msg);\n        }","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/security/DefaultMacAlgorithm.java#L126-L162","documentation":"InvalidKeyException from DefaultMacAlgorithm.assertAlgorithmName when the key's JCA algorithm name is present but is neither a valid HmacSHA* name nor a PKCS12 OID matching the JWA standard MAC algorithm being used, and the key is not a 'generic secret'. Only applies to JWA-standard algorithms (HS256/HS384/HS512).","triggerScenarios":"Passing a SecretKeySpec with algorithm \"AES\" (e.g. a content-encryption key) to signWith/verifyWith HS256; a key named \"HSMKEY\" from a provider that is not flagged as a generic secret; using an HmacSHA256 key with the HS384 algorithm.","commonSituations":"Reusing an AES key object for JWT signing; keys loaded from PKCS#12 keystores with OID names that don't match; provider-specific algorithm naming that isn't recognized as a generic secret.","solutions":["Use a key whose algorithm matches the MAC algorithm: new SecretKeySpec(bytes, \"HmacSHA256\") with HS256.","Create the key with Keys.hmacShaKeyFor(bytes) or Jwts.SIG.HS256.key().build().","Use a distinct signing key instead of reusing an AES encryption key.","If the key is truly a generic secret from an HSM, ensure KeysBridge recognizes it as generic (correct algorithm naming) or use a standard-named key."],"exampleFix":"// before\nSecretKey key = new SecretKeySpec(rawBytes, \"AES\");\nJwtParser p = Jwts.parser().verifyWith(key).build(); // HS256\n// after\nSecretKey key = Keys.hmacShaKeyFor(rawBytes); // -> HmacSHA256 sized key\nJwtParser p = Jwts.parser().verifyWith(key).build();","handlingStrategy":"validation","validationCode":"static boolean isHmacNamedKey(Key k, String macJcaName) {\n    String n = k == null ? null : k.getAlgorithm();\n    return n != null && n.replace(\"-\", \"\").equalsIgnoreCase(macJcaName.replace(\"-\", \"\"));\n}\n// require isHmacNamedKey(key, \"HmacSHA256\") before HS256","typeGuard":"boolean matchesMacAlg(SecretKey k, MacAlgorithm alg) {\n    return k.getAlgorithm() != null && k.getAlgorithm().toUpperCase().contains(\"HMACSHA\");\n}","tryCatchPattern":"try {\n    return parser.verifyWith(key).build().parseSignedClaims(jwt);\n} catch (InvalidKeyException e) {\n    logger.error(\"Key algorithm '{}' not usable with HS256; rebuilding key\", key.getAlgorithm());\n    return parser.verifyWith(Keys.hmacShaKeyFor(key.getEncoded())).build().parseSignedClaims(jwt);\n}","preventionTips":["Create MAC keys only via Keys.hmacShaKeyFor or Jwts.SIG.HS*.key().build()","Never reuse AES content-encryption keys for JWT signing","Verify keystore-derived keys are secret keys with HmacSHA* names","Match algorithm name to the HS variant (HmacSHA256 <-> HS256)"],"tags":["java","jjwt","mac","algorithm-mismatch","hmac"],"backgroundTag":"invalid-argument-value","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"}