暗号化された SAML アサーションを受け取る Web サービスを作成しています。SAML アサーションが暗号化される前に検証できました。
サービスが EncryptedAssertion を復号化すると、アサーション署名を検証できません
その理由を調べるために、次のような小さなテストを作成しました。
- 署名されたアサーション (検証可能) を作成します - assertion1
- assertion1 の署名を検証しました - このテストはパスします
- assertion1 を暗号化して EncryptedAssertion を取得します
- EncryptedAssertion を復号化してアサーションを取得します - assertion2
- assertion2 の署名を検証します - このテストは失敗します
assertion1 ノードと assertion2 ノードを比較すると、違いは 1 つだけです。Assertion1 では、xmldsig 名前空間が Assertion ルート要素と ds:Signature 要素の両方で宣言されています。Assertion2 では、Signature 要素の xmldsig 名前空間宣言が削除されています。
XML に関しては、これは完全に有効な変換であり、XML は引き続き有効です。私の問題は、この変更が行われると、アサーションの署名が現在欠落しているプレフィックス宣言を考慮に入れているため、署名が無効になることです。
OpenSAML Encrypter/Decrypter に、受信した XML を「改善」しないように指示し、最初に入力として使用されたものを Encrypter に返す方法はありますか?
xmldsig 名前空間の 2 つの宣言を含む XML を構築するクライアントを変更することは、実際にはオプションではありません。そうですね。しかし、このサービスのクライアントは別の会社によって開発されており、可能であれば、この種の入力の問題に対してサービスを堅牢にしたいと考えています。
assertion1 を暗号化するテスト コードは次のとおりです。
public static EncryptedAssertion encryptAssertion(Assertion assertion, Credential credential) {
EncryptionParameters encParams = new EncryptionParameters();
encParams.setAlgorithm(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128);
KeyEncryptionParameters kekParams = new KeyEncryptionParameters();
kekParams.setEncryptionCredential(credential);
kekParams.setAlgorithm(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP);
KeyInfoGeneratorFactory kigf =
Configuration.getGlobalSecurityConfiguration()
.getKeyInfoGeneratorManager().getDefaultManager()
.getFactory(credential);
kekParams.setKeyInfoGenerator(kigf.newInstance());
Encrypter samlEncrypter = new Encrypter(encParams, kekParams);
samlEncrypter.setKeyPlacement(Encrypter.KeyPlacement.INLINE);
try {
return samlEncrypter.encrypt(assertion);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
これは、EncryptedAssertion を復号化するテスト コードです。
public static Assertion decryptEncryptedAssertion(EncryptedAssertion encryptedAssertion, Credential credentials) throws DecryptionException {
StaticKeyInfoCredentialResolver staticKeyResolver = new StaticKeyInfoCredentialResolver(credentials);
InlineEncryptedKeyResolver inlineEncryptedKeyResolver = new InlineEncryptedKeyResolver();
Decrypter decrypter = new Decrypter(null, staticKeyResolver, inlineEncryptedKeyResolver);
return decrypter.decrypt(encryptedAssertion);
}
これは assertion1 の始まりです:
<?xml version="1.0" encoding="UTF-8"?><saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_ede6280e-d094-4b74-a67a-e70bbec6f3e9" IssueInstant="2014-06-23T09:42:33.970Z" Version="2.0" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameidformat:entity">https://sts.sundhed.dk</saml2:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
これは assertion2 の始まりです。assertion1 と比較して、Signature ノードの xmlns:ds 宣言が欠落していることに注意してください。
<?xml version="1.0" encoding="UTF-8"?><saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_ede6280e-d094-4b74-a67a-e70bbec6f3e9" IssueInstant="2014-06-23T09:42:33.970Z" Version="2.0" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameidformat:entity">https://sts.sundhed.dk</saml2:Issuer>
<ds:Signature>
<ds:SignedInfo>
更新: これは、assertion2 の署名を検証しようとしたときに発生する例外です (復号化後に xmlns:ds がない場合)。回答で提案されているように decrypter.setRootInNewDocument(true) を呼び出すと、検証呼び出しが正常に完了します。
org.opensaml.xml.validation.ValidationException: Unable to evaluate key against signature
at org.opensaml.xml.signature.SignatureValidator.validate(SignatureValidator.java:74)
at dk.itst.oiosaml.sp.model.OIOSamlObject.verifySignature(OIOSamlObject.java:239)
at dk.medicinkortet.idws.impl.EncryptedAssertionHandlerImplTest.testDecrypt(EncryptedAssertionHandlerImplTest.java:152)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: org.apache.xml.security.signature.MissingResourceFailureException: The Reference for URI #_944e39b7-37e2-4cd1-baba-865fb17f645b has no XMLSignatureInput
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID _944e39b7-37e2-4cd1-baba-865fb17f645b
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID _944e39b7-37e2-4cd1-baba-865fb17f645b
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID _944e39b7-37e2-4cd1-baba-865fb17f645b
Original Exception was org.apache.xml.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID _944e39b7-37e2-4cd1-baba-865fb17f645b
at org.apache.xml.security.signature.Manifest.verifyReferences(Manifest.java:414)
at org.apache.xml.security.signature.SignedInfo.verify(SignedInfo.java:256)
at org.apache.xml.security.signature.XMLSignature.checkSignatureValue(XMLSignature.java:728)
at org.opensaml.xml.signature.SignatureValidator.validate(SignatureValidator.java:69)
... 34 more
Caused by: org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID _944e39b7-37e2-4cd1-baba-865fb17f645b
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID _944e39b7-37e2-4cd1-baba-865fb17f645b
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID _944e39b7-37e2-4cd1-baba-865fb17f645b
Original Exception was org.apache.xml.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID _944e39b7-37e2-4cd1-baba-865fb17f645b
at org.apache.xml.security.signature.Reference.calculateDigest(Reference.java:732)
at org.apache.xml.security.signature.Reference.verify(Reference.java:775)
at org.apache.xml.security.signature.Manifest.verifyReferences(Manifest.java:336)
... 37 more
Caused by: org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID _944e39b7-37e2-4cd1-baba-865fb17f645b
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID _944e39b7-37e2-4cd1-baba-865fb17f645b
Original Exception was org.apache.xml.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID _944e39b7-37e2-4cd1-baba-865fb17f645b
at org.apache.xml.security.signature.Reference.dereferenceURIandPerformTransforms(Reference.java:604)
at org.apache.xml.security.signature.Reference.calculateDigest(Reference.java:706)
... 39 more
Caused by: org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID _944e39b7-37e2-4cd1-baba-865fb17f645b
Original Exception was org.apache.xml.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID _944e39b7-37e2-4cd1-baba-865fb17f645b
at org.apache.xml.security.signature.Reference.getContentsBeforeTransformation(Reference.java:419)
at org.apache.xml.security.signature.Reference.dereferenceURIandPerformTransforms(Reference.java:597)
... 40 more
Caused by: org.apache.xml.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID _944e39b7-37e2-4cd1-baba-865fb17f645b
at org.apache.xml.security.utils.resolver.implementations.ResolverFragment.engineResolveURI(ResolverFragment.java:85)
at org.apache.xml.security.utils.resolver.ResourceResolver.resolve(ResourceResolver.java:298)
at org.apache.xml.security.signature.Reference.getContentsBeforeTransformation(Reference.java:417)
... 41 more