justauth/JustAuth · error · AuthException
Invalid key: ${Arrays.toString(key)}
Error message
Invalid key: ${Arrays.toString(key)} What it means
Internal guard in GlobalAuthUtils.sign: SecretKeySpec/Mac.init threw InvalidKeyException, i.e. the key bytes are unusable for the requested MAC. In practice this means the key material was null-derived or degenerate — typically an empty client-secret/agent credential reaching the signature path. The message leaks the raw key bytes via Arrays.toString(key), which itself is worth noting for log hygiene with real secrets.
Source
Thrown at src/main/java/me/zhyd/oauth/utils/GlobalAuthUtils.java:57
}
/**
* 签名
*
* @param key key
* @param data data
* @param algorithm algorithm
* @return byte[]
*/
private static byte[] sign(byte[] key, byte[] data, String algorithm) {
try {
Mac mac = Mac.getInstance(algorithm);
mac.init(new SecretKeySpec(key, algorithm));
return mac.doFinal(data);
} catch (NoSuchAlgorithmException ex) {
throw new AuthException("Unsupported algorithm: " + algorithm, ex);
} catch (InvalidKeyException ex) {
throw new AuthException("Invalid key: " + Arrays.toString(key), ex);
}
}
/**
* 编码
*
* @param value str
* @return encode str
*/
public static String urlEncode(String value) {
if (value == null) {
return "";
}
try {
String encoded = URLEncoder.encode(value, GlobalAuthUtils.DEFAULT_ENCODING.displayName());
return encoded.replace("+", "%20").replace("*", "%2A").replace("~", "%7E").replace("/", "%2F");
} catch (UnsupportedEncodingException e) {
throw new AuthException("Failed To Encode Uri", e);View on GitHub (pinned to 694bbf1b01)
Solutions
- Verify the secret is non-empty before calling the SDK flow that signs requests (Douyin/DingTalk style agents): log config.getClientSecret() != null && !isBlank, never the value itself.
- Check which credential maps to the signing key for that platform — some (e.g. agentId/clientSecret) are easily swapped.
- Load-test profiles: ensure the same config source is used in test and prod.
- If you control the code path, reject empty secrets at startup instead of letting sign() fail mid-request.
Example fix
// before
AuthConfig cfg = AuthConfig.builder().clientId(id).redirectUri(uri).build(); // secret forgotten
new AuthDingTalkRequest(cfg, cache).getAccessToken(callback);
// after
if (StringUtil.isEmpty(cfg.getClientSecret())) {
throw new IllegalStateException("clientSecret required for this platform");
}
AuthConfig cfg = AuthConfig.builder().clientId(id).clientSecret(secret).redirectUri(uri).build(); Defensive patterns
Strategy: validation
Validate before calling
if (StringUtils.isEmpty(config.getClientSecret())) {
throw new IllegalStateException("clientSecret is required for " + source.getName());
} Try / catch
catch (AuthException e) { if (e.getMessage() != null && e.getMessage().startsWith("Invalid key:")) { /* credential missing/mismatched — never log the key bytes this message contains */ } } Prevention
- Assert all required credentials non-empty at startup per platform.
- Use secret managers or env binding instead of hand-edited YAML to avoid silent blanks.
- Never log this exception's message verbatim in production — it embeds the raw key bytes.
When it happens
Trigger: A JustAuth request class calls GlobalAuthUtils.sign (or exchangeCgtx/dingtalk-style signing) with a byte[] key built from a secret that is null or zero-length, e.g. config.getClientSecret() missing while a signature-secured endpoint is invoked. Note: a null SecretKeySpec constructor usually fails earlier with IllegalArgumentException, so the realistic path is a provider/key mismatch or empty-key edge on certain JVMs.
Common situations: AuthConfig built from env vars where the secret variable was unset; YAML indentation hiding the secret key; credentials swapped (clientId used as secret); provider config objects partially populated in tests/mocks.
Related errors
AI-assisted analysis of justauth/JustAuth@694bbf1b01 (2026-08-14).
Data as JSON: /api/errors/f08784f3639b0d1c.
Report an issue: GitHub.