{"record":{"id":"6e89819840785930","repo":"spring-projects/spring-security","slug":"saml2exception-wrapping-decryptionexception-during-6e8981","errorCode":null,"errorMessage":"Saml2Exception wrapping DecryptionException during encrypted assertion decryption","messagePattern":"Saml2Exception wrapping DecryptionException during encrypted assertion decryption","errorType":"exception","errorClass":"Saml2Exception","httpStatus":null,"severity":"error","filePath":"saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/web/OpenSaml5Template.java","lineNumber":518,"sourceCode":"\t\t */\n\n\t\tprivate void decryptResponse(Response response) {\n\t\t\tCollection<Assertion> decrypteds = new ArrayList<>();\n\n\t\t\tint count = 0;\n\t\t\tint size = response.getEncryptedAssertions().size();\n\t\t\tfor (EncryptedAssertion encrypted : response.getEncryptedAssertions()) {\n\t\t\t\tlogger.trace(String.format(\"Decrypting EncryptedAssertion (%d/%d) in Response [%s]\", count, size,\n\t\t\t\t\t\tresponse.getID()));\n\t\t\t\ttry {\n\t\t\t\t\tAssertion decrypted = this.decrypter.decrypt(encrypted);\n\t\t\t\t\tif (decrypted != null) {\n\t\t\t\t\t\tdecrypteds.add(decrypted);\n\t\t\t\t\t}\n\t\t\t\t\tcount++;\n\t\t\t\t}\n\t\t\t\tcatch (DecryptionException ex) {\n\t\t\t\t\tthrow new Saml2Exception(ex);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tresponse.getAssertions().addAll(decrypteds);\n\n\t\t\t// Re-marshall the response so that any ID attributes within the decrypted\n\t\t\t// Assertions\n\t\t\t// will have their ID-ness re-established at the DOM level.\n\t\t\tif (!decrypteds.isEmpty()) {\n\t\t\t\ttry {\n\t\t\t\t\tXMLObjectSupport.marshall(response);\n\t\t\t\t}\n\t\t\t\tcatch (final MarshallingException ex) {\n\t\t\t\t\tthrow new Saml2Exception(ex);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n","sourceCodeStart":500,"sourceCodeEnd":536,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/web/OpenSaml5Template.java#L500-L536","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Register the IdP's encryption certificate as a decryption credential on the RelyingPartyRegistration (decryptionX509Certificate)","Confirm the private key corresponding to that certificate is available and loadable","Align encryption algorithms: configure the IdP to use algorithms your JVM/decrypter supports","Inspect the wrapped DecryptionException cause for the specific key/algorithm failure"],"exampleFix":"// before\nRelyingPartyRegistration.withRegistrationId(\"idp\") // no decryption cert\n// after\n.decryptionX509Certificate(idpEncryptionCertificate)\n.build()","handlingStrategy":"try-catch","validationCode":"boolean hasEncryptedAssertions = response.getEncryptedAssertions() != null && !response.getEncryptedAssertions().isEmpty();\nif (hasEncryptedAssertions && decryptionCredentials.isEmpty()) throw new Saml2ConfigurationException(\"Encrypted assertions but no decryption credentials\");","typeGuard":null,"tryCatchPattern":"try { template.decrypt(response); } catch (Saml2Exception e) { log.error(\"Assertion decryption failed\", e.getCause()); return new Saml2Error(\"decryption\", \"Unable to decrypt assertion\"); }","preventionTips":["Register decryptionX509Certificate matching the IdP's encryption cert","Monitor IdP metadata for encryption-cert rotation","Keep JVM crypto policy current (unlimited strength / AES-GCM support)","Log the DecryptionException cause"],"tags":["saml","decryption","encryption","spring-security"],"backgroundTag":"decryption-failed","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}