{"record":{"id":"3ca119d68f6819b3","repo":"spring-projects/spring-security","slug":"saml2exception-wrapping-decryptionexception-during-3ca119","errorCode":null,"errorMessage":"Saml2Exception wrapping DecryptionException during encrypted subject-confirmation NameID decryption","messagePattern":"Saml2Exception wrapping DecryptionException during encrypted subject-confirmation NameID decryption","errorType":"exception","errorClass":"Saml2Exception","httpStatus":null,"severity":"error","filePath":"saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/metadata/OpenSaml5Template.java","lineNumber":603,"sourceCode":"\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}\n\n\t\tprivate void decryptLogoutRequest(LogoutRequest request) {\n\t\t\tif (request.getEncryptedID() != null) {\n\t\t\t\ttry {\n\t\t\t\t\tNameID decrypted = (NameID) this.decrypter.decrypt(request.getEncryptedID());\n\t\t\t\t\tif (decrypted != null) {\n\t\t\t\t\t\trequest.setNameID(decrypted);\n\t\t\t\t\t}\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}","sourceCodeStart":585,"sourceCodeEnd":621,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/metadata/OpenSaml5Template.java#L585-L621","documentation":"decryptSubject also decrypts encrypted NameIDs inside each SubjectConfirmation; DecryptionException is wrapped in Saml2Exception. Thrown because failure to decrypt a subject-confirmation NameID prevents validating the SubjectConfirmation, which is required for bearer/HoK confirmation.","triggerScenarios":"Calling decrypt(...) where a SubjectConfirmation's EncryptedID exists but decryption fails with the configured Decrypter.","commonSituations":"IDP uses distinct certificates for subject-confirmation encryption; SP missing private key; OpenSAML 5 algorithm restrictions; expired/rotated IDP keys still cached in SP metadata.","solutions":["Ensure the decryption credential matches the certificate the IDP used for the SubjectConfirmation EncryptedID.","Inspect the wrapped DecryptionException cause to target the exact failure (key vs algorithm).","Refresh cached IDP metadata so rotated keys are picked up.","Verify with the IDP team that subject-confirmation NameID encryption is intended and correctly configured."],"exampleFix":"// before\n// SP holds only the old certificate\n// after\n// re-import metadata containing the new IDP encryption cert and rebuild registration\nreg = RelyingPartyRegistration.withRegistrationId(\"idp\")\n    .decryptionX509Credentials(c -> c.add(newCredentialFromRefreshedMetadata))\n    .build();","handlingStrategy":"validation","validationCode":"Assert.notEmpty(registration.getDecryptionX509Credentials(), \"decryption credentials required for SubjectConfirmation NameIDs\");","typeGuard":null,"tryCatchPattern":"try {\n    template.decrypt(response);\n} catch (Saml2Exception ex) {\n    if (ex.getCause() instanceof DecryptionException) {\n        logger.error(\"SubjectConfirmation NameID decryption failed: {}\", ex.getCause().getMessage());\n    }\n}","preventionTips":["Ask the IDP which certificate it uses for subject-confirmation NameID encryption.","Keep cached IDP metadata refreshed so rotated keys are loaded.","Test full decryption of real IDP responses in a staging environment."],"tags":["saml2","decryption","subject-confirmation","opensaml5"],"backgroundTag":"missing-credentials","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"}