spring-projects/spring-security · error · Saml2Exception

Saml2Exception wrapping DecryptionException during encrypted

Error message

Saml2Exception wrapping DecryptionException during encrypted assertion decryption

What it means

After validating a SAML Response, OpenSaml5Template decrypts any EncryptedAssertion elements using an OpenSAML Decrypter; a DecryptionException is rethrown as Saml2Exception. Decryption fails when the encrypted assertion's algorithm/key cannot be handled with the configured decryption credentials.

Source

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

		 */

		private void decryptResponse(Response response) {
			Collection<Assertion> decrypteds = new ArrayList<>();

			int count = 0;
			int size = response.getEncryptedAssertions().size();
			for (EncryptedAssertion encrypted : response.getEncryptedAssertions()) {
				logger.trace(String.format("Decrypting EncryptedAssertion (%d/%d) in Response [%s]", count, size,
						response.getID()));
				try {
					Assertion decrypted = this.decrypter.decrypt(encrypted);
					if (decrypted != null) {
						decrypteds.add(decrypted);
					}
					count++;
				}
				catch (DecryptionException ex) {
					throw new Saml2Exception(ex);
				}
			}

			response.getAssertions().addAll(decrypteds);

			// Re-marshall the response so that any ID attributes within the decrypted
			// Assertions
			// will have their ID-ness re-established at the DOM level.
			if (!decrypteds.isEmpty()) {
				try {
					XMLObjectSupport.marshall(response);
				}
				catch (final MarshallingException ex) {
					throw new Saml2Exception(ex);
				}
			}
		}

View on GitHub (pinned to 96852e8860)

Solutions

  1. Register the IdP's encryption certificate as a decryption credential on the RelyingPartyRegistration (decryptionX509Certificate)
  2. Confirm the private key corresponding to that certificate is available and loadable
  3. Align encryption algorithms: configure the IdP to use algorithms your JVM/decrypter supports
  4. Inspect the wrapped DecryptionException cause for the specific key/algorithm failure

Example fix

// before
RelyingPartyRegistration.withRegistrationId("idp") // no decryption cert
// after
.decryptionX509Certificate(idpEncryptionCertificate)
.build()
Defensive patterns

Strategy: try-catch

Validate before calling

boolean hasEncryptedAssertions = response.getEncryptedAssertions() != null && !response.getEncryptedAssertions().isEmpty();
if (hasEncryptedAssertions && decryptionCredentials.isEmpty()) throw new Saml2ConfigurationException("Encrypted assertions but no decryption credentials");

Try / catch

try { template.decrypt(response); } catch (Saml2Exception e) { log.error("Assertion decryption failed", e.getCause()); return new Saml2Error("decryption", "Unable to decrypt assertion"); }

Prevention

When it happens

Trigger: decrypt()/decryptResponse() processing a Response containing <saml2:EncryptedAssertion> where the Decrypter has no matching decryption key, the EncryptedKey cannot be resolved, or the encryption algorithm/key transport is unsupported.

Common situations: Identity provider encrypts assertions with a certificate the SP has not registered as a decryption credential; wrong keystore configured in RelyingPartyRegistration; IdP switched to a newer encryption algorithm (e.g. RSA-OAEP or AES-GCM) not supported by the JVM policy or the configured decrypter.

Related errors


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