spring-projects/spring-security · error · IllegalArgumentException

Only RSA is currently supported, but algorithm was

Error message

Only RSA is currently supported, but algorithm was 

What it means

RsaKeyHelper.extractPublicKey parses SSH public key strings of the form 'ssh-rsa AAAA... comment'. After regex-extracting the algorithm name and base64 payload it requires the algorithm to be 'rsa' (case-insensitive). Any other algorithm name triggers this IllegalArgumentException.

Source

Thrown at crypto/src/main/java/org/springframework/security/crypto/encrypt/RsaKeyHelper.java:178

		catch (NoSuchAlgorithmException ex) {
			throw new IllegalStateException(ex);
		}

	}

	private static final Pattern SSH_PUB_KEY = Pattern.compile("ssh-(rsa|dsa) ([A-Za-z0-9/+]+=*) (.*)");

	private static @Nullable RSAPublicKey extractPublicKey(String key) {

		Matcher m = SSH_PUB_KEY.matcher(key);

		if (m.matches()) {
			String alg = m.group(1);
			String encKey = m.group(2);
			// String id = m.group(3);

			if (!"rsa".equalsIgnoreCase(alg)) {
				throw new IllegalArgumentException("Only RSA is currently supported, but algorithm was " + alg);
			}

			return parseSSHPublicKey(encKey);
		}
		else if (!key.startsWith(BEGIN)) {
			// Assume it's the plain Base64 encoded ssh key without the
			// "ssh-rsa" at the start
			return parseSSHPublicKey(key);
		}

		return null;
	}

	static RSAPublicKey parsePublicKey(String key) {

		RSAPublicKey publicKey = extractPublicKey(key);

		if (publicKey != null) {

View on GitHub (pinned to 96852e8860)

Solutions

  1. Regenerate the key as RSA: ssh-keygen -t rsa -b 2048 (or 4096) and supply that key.
  2. Use a parser that supports the key's actual algorithm (e.g. java security providers or sshd-common) instead of RsaKeyHelper.
  3. If the key file contains multiple key types, pick the rsa entry from the authorized_keys/id_rsa.pub file rather than id_ed25519.pub.
  4. Strip surrounding whitespace/lines so the first token is genuinely the algorithm field.

Example fix

// before
String key = Files.readString(Path.of("~/.ssh/id_ed25519.pub"));
PublicKey pk = helper.extractPublicKey(key);
// after
String key = Files.readString(Path.of("~/.ssh/id_rsa.pub"));
PublicKey pk = helper.extractPublicKey(key);
Defensive patterns

Strategy: validation

Validate before calling

if (!key.trim().startsWith("ssh-rsa ")) {
    throw new IllegalArgumentException("Only ssh-rsa keys are supported, got: " + key.split("\\s+")[0]);
}

Type guard

boolean isRsaSshKey(String key) {
    String[] parts = key == null ? new String[0] : key.trim().split("\\s+");
    return parts.length >= 2 && "rsa".equalsIgnoreCase(parts[0]);
}

Try / catch

try {
    RSAPublicKey pk = helper.extractPublicKey(key);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("Only RSA")) {
        throw new ConfigException("Provide an ssh-rsa public key (regenerate with: ssh-keygen -t rsa -b 4096)");
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling extractPublicKey/publicKey with a key string whose first token is not 'rsa', e.g. 'ssh-ed25519 AAAA...' or 'ecdsa-sha2-nistp256 AAAA...'.

Common situations: Users generate modern SSH keys with ssh-keygen -t ed25519 (now the default recommendation) or ECDSA and paste them into configuration expecting RSA-only helpers to accept them.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/3f55fe8f3ba02066. Report an issue: GitHub.