spring-projects/spring-security · error · Saml2Exception

Saml2Exception wrapping DecryptionException during encrypted

Error message

Saml2Exception wrapping DecryptionException during encrypted subject-confirmation NameID decryption

What it means

OpenSaml5Template.decryptSubject also iterates SubjectConfirmations and decrypts each <saml2:EncryptedID> inside them. A DecryptionException there is wrapped in a Saml2Exception. This means an encrypted NameID embedded in a SubjectConfirmation (common in Holder-of-Key / bearer confirmation) failed to decrypt.

Source

Thrown at saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/registration/OpenSaml5Template.java:603

						if (decrypted != null) {
							subject.setNameID(decrypted);
						}
					}
					catch (final DecryptionException ex) {
						throw new Saml2Exception(ex);
					}
				}

				for (final SubjectConfirmation sc : subject.getSubjectConfirmations()) {
					if (sc.getEncryptedID() != null) {
						try {
							NameID decrypted = (NameID) this.decrypter.decrypt(sc.getEncryptedID());
							if (decrypted != null) {
								sc.setNameID(decrypted);
							}
						}
						catch (final DecryptionException ex) {
							throw new Saml2Exception(ex);
						}
					}
				}
			}
		}

		private void decryptLogoutRequest(LogoutRequest request) {
			if (request.getEncryptedID() != null) {
				try {
					NameID decrypted = (NameID) this.decrypter.decrypt(request.getEncryptedID());
					if (decrypted != null) {
						request.setNameID(decrypted);
					}
				}
				catch (DecryptionException ex) {
					throw new Saml2Exception(ex);
				}
			}

View on GitHub (pinned to 96852e8860)

Solutions

  1. Register all decryption credentials the IdP may use, including those for SubjectConfirmation EncryptedIDs
  2. Check the caught DecryptionException and its KeyInfo against each registered certificate
  3. Confirm key agreement/key-transport algorithms (RSA-OAEP, ECDH-ES) are supported by the JVM
  4. Sync encryption certificates in both SP and IdP metadata

Example fix

// before
c -> c.add(credA) // only one decryption credential
// after
c -> c.add(credA).add(credB) // all certs the IdP may encrypt to
Defensive patterns

Strategy: try-catch

Validate before calling

for (SubjectConfirmation sc : subject.getSubjectConfirmations()) {
    if (sc.getEncryptedID() != null && registration.getDecryptionX509Credentials().isEmpty())
        throw new IllegalStateException("Encrypted SubjectConfirmation NameID without credentials");
}

Type guard

if (sc.getEncryptedID() == null && sc.getNameID() != null) { /* already plain */ }

Try / catch

try {
    decryptSubject(subject);
} catch (Saml2Exception ex) {
    if (ex.getCause() instanceof DecryptionException)
        logger.warn("SubjectConfirmation NameID decryption failed");
    throw ex;
}

Prevention

When it happens

Trigger: decryptAssertion -> decryptSubject when SubjectConfirmation(s) contain EncryptedID elements; decryption credentials don't match or the ciphertext/algorithm is unsupported.

Common situations: IdP encrypts the SubjectConfirmation NameID with a different certificate than the subject NameID; SP only registered one decryption key; proxy/pass-through SSO flows where an intermediary's key was expected.

Related errors


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