{"record":{"id":"6a58d45905daaa93","repo":"spring-projects/spring-security","slug":"saml2exception-wrapping-decryptionexception-during-6a58d4","errorCode":null,"errorMessage":"Saml2Exception wrapping DecryptionException during encrypted subject NameID decryption","messagePattern":"Saml2Exception wrapping DecryptionException during encrypted subject NameID decryption","errorType":"exception","errorClass":"Saml2Exception","httpStatus":null,"severity":"error","filePath":"saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/registration/OpenSaml5Template.java","lineNumber":590,"sourceCode":"\t\t\t\t}\n\t\t\t\tcatch (Exception ex) {\n\t\t\t\t\tthrow new Saml2Exception(ex);\n\t\t\t\t}\n\t\t\t}\n\t\t\tstatement.getAttributes().addAll(decrypteds);\n\t\t}\n\n\t\tprivate void decryptSubject(@Nullable Subject subject) {\n\t\t\tif (subject != null) {\n\t\t\t\tif (subject.getEncryptedID() != null) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tNameID decrypted = (NameID) this.decrypter.decrypt(subject.getEncryptedID());\n\t\t\t\t\t\tif (decrypted != null) {\n\t\t\t\t\t\t\tsubject.setNameID(decrypted);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcatch (final DecryptionException ex) {\n\t\t\t\t\t\tthrow new Saml2Exception(ex);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor (final SubjectConfirmation sc : subject.getSubjectConfirmations()) {\n\t\t\t\t\tif (sc.getEncryptedID() != null) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tNameID decrypted = (NameID) this.decrypter.decrypt(sc.getEncryptedID());\n\t\t\t\t\t\t\tif (decrypted != null) {\n\t\t\t\t\t\t\t\tsc.setNameID(decrypted);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (final DecryptionException ex) {\n\t\t\t\t\t\t\tthrow new Saml2Exception(ex);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}","sourceCodeStart":572,"sourceCodeEnd":608,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/registration/OpenSaml5Template.java#L572-L608","documentation":"OpenSaml5Template.decryptSubject decrypts the <saml2:Subject>'s <saml2:EncryptedID>. A DecryptionException from the OpenSAML Decrypter is wrapped in a Saml2Exception. This means the encrypted NameID at the subject level of the assertion could not be decrypted.","triggerScenarios":"decryptAssertion -> decryptSubject on a Response where the Subject carries an EncryptedID; the decrypter lacks the matching private key, or the encrypted element uses an unsupported/malformed format.","commonSituations":"IdP configured with 'encrypt NameID' but SP never shared the correct encryption certificate in metadata; SP key rotated without updating IdP metadata; wrong RelyingPartyRegistration resolved for the response.","solutions":["Ensure the IdP's NameID encryption certificate matches an entry in RelyingPartyRegistration.decryptionX509Credentials","Re-publish updated SP encryption metadata to the IdP after key rotation","Inspect the caught DecryptionException cause to distinguish 'no key' from 'bad algorithm/ciphertext'","Verify the response's issuer maps to the registration holding the right keys"],"exampleFix":"// before\n.metadata.input(...) // SP metadata exposes stale encryption cert\n// after\n.metadata.input(...) .processing(ctx -> ctx.decryptionX509Credentials(c -> c.add(newCred))) // refresh creds and republish metadata","handlingStrategy":"try-catch","validationCode":"if (assertion.getSubject() != null && assertion.getSubject().getEncryptedID() != null\n    && registration.getDecryptionX509Credentials().isEmpty())\n    throw new IllegalStateException(\"Encrypted subject NameID but no decryption credentials\");","typeGuard":"if (subject.getEncryptedID() == null || subject.getNameID() != null) { /* already resolvable */ }","tryCatchPattern":"try {\n    decryptSubject(subject);\n} catch (Saml2Exception ex) {\n    throw new Saml2Exception(\"Failed to decrypt subject NameID: \" + ex.getCause(), ex);\n}","preventionTips":["Ensure the SP encryption certificate published in metadata is the one the IdP encrypts NameIDs to","Re-export SP metadata to the IdP after any keystore change","Monitor for key-rotation announcements from the IdP"],"tags":["saml2","decryption","nameid","subject","spring-security"],"backgroundTag":"saml-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"}