{"record":{"id":"dea74afe5f0313f6","repo":"spring-projects/spring-security","slug":"saml2exception-wrapping-decryptionexception-during-dea74a","errorCode":null,"errorMessage":"Saml2Exception wrapping DecryptionException during encrypted NameID decryption","messagePattern":"Saml2Exception wrapping DecryptionException during encrypted NameID 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":556,"sourceCode":"\t\t\tfor (AttributeStatement statement : assertion.getAttributeStatements()) {\n\t\t\t\tdecryptAttributes(statement);\n\t\t\t}\n\t\t\tdecryptSubject(assertion.getSubject());\n\t\t\tif (assertion.getConditions() != null) {\n\t\t\t\tfor (Condition c : assertion.getConditions().getConditions()) {\n\t\t\t\t\tif (!(c instanceof DelegationRestrictionType delegation)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tfor (Delegate d : delegation.getDelegates()) {\n\t\t\t\t\t\tif (d.getEncryptedID() != null) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tNameID decrypted = (NameID) this.decrypter.decrypt(d.getEncryptedID());\n\t\t\t\t\t\t\t\tif (decrypted != null) {\n\t\t\t\t\t\t\t\t\td.setNameID(decrypted);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch (DecryptionException ex) {\n\t\t\t\t\t\t\t\tthrow new Saml2Exception(ex);\n\t\t\t\t\t\t\t}\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 decryptAttributes(AttributeStatement statement) {\n\t\t\tCollection<Attribute> decrypteds = new ArrayList<>();\n\t\t\tfor (EncryptedAttribute encrypted : statement.getEncryptedAttributes()) {\n\t\t\t\ttry {\n\t\t\t\t\tAttribute 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}\n\t\t\t\tcatch (Exception ex) {\n\t\t\t\t\tthrow new Saml2Exception(ex);","sourceCodeStart":538,"sourceCodeEnd":574,"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#L538-L574","documentation":"When decrypting an AttributeStatement, OpenSaml5Template decrypts each Statement's <EncryptedID> into a NameID; a DecryptionException is rethrown as Saml2Exception. It means the encrypted identifier could not be decrypted with the configured decryption credentials.","triggerScenarios":"decryptAssertion() traversing AttributeStatements that contain <EncryptedID>, calling this.decrypter.decrypt(d.getEncryptedID()) when the decryption key does not match the encryption key or the algorithm is unsupported.","commonSituations":"IdP encrypts attribute NameIDs with a key rotation the SP hasn't picked up; SP configured only the signing certificate, not the encryption/decryption certificate; JVM lacks support for the IdP's key-wrap algorithm.","solutions":["Ensure the decryption credential matching the IdP's encryption certificate is registered and its private key is present","Check for IdP key rotation and update the SP's keystore","Agree with the IdP on supported encryption algorithms (e.g. aes128-cbc vs aes256-gcm, rsa-1_5 vs rsa-oaep)","Catch Saml2Exception and inspect cause DecryptionException for key resolution failure details"],"exampleFix":"// before\n.decryptionX509Certificate(oldIdpEncryptionCert) // stale after IdP key rotation\n// after\n.decryptionX509Certificate(currentIdpEncryptionCert)\n.build()","handlingStrategy":"try-catch","validationCode":"if (statement.getEncryptedIDs().stream().anyMatch(e -> e != null) && !hasMatchingDecryptionKey(statement)) throw new Saml2ConfigurationException(\"No key for encrypted attribute NameID\");","typeGuard":null,"tryCatchPattern":"try { decrypted = decrypter.decrypt(encryptedId); } catch (Saml2Exception e) { log.warn(\"Encrypted attribute NameID failed: \" + e.getCause()); }","preventionTips":["Register all IdP encryption certs (rotation overlap)","Align attribute NameID encryption settings with the IdP admins","Handle decryption failure per-statement so one bad statement doesn't fail the whole response where policy allows"],"tags":["saml","decryption","nameid","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"}