My understanding of XML Digital Signatures:
Let's use a SAML token as an example.
Note - for the sake of simplicity I'm omitting some details like CanonicalizationMethod, base64 encoding, etc.
In order for me to sign the <saml:Assertion>
node I use a private/public key pair:
- Create a hash of the
<saml:Assertion>
block and store it in a<ds:Reference>
inside the<ds:SignedInfo>
node. - Use the private key to encrypt the
<ds:SignedInfo>
node and store it in the<ds:SignatureValue>
node. - Pass the public certificate in the
<ds:KeyInfo>
block.
To verify the signature I then:
- decrypt the
<ds:SignatureValue>
node using the public certificate found in<ds:KeyInfo>
and ensure that it is equal to the<ds:SignedInfo>
block - ensure that the hash of the
<saml:Assertion>
node is equal to the digest stored in the<ds:Reference>
node.
My question:
What I don't understand is that in my opinion this doesn't verify the sender, it simply verifies that the private key component of the public certificate sent in the <ds:KeyInfo>
node was used to sign the token. An attacker could create his own certificate pair and sign the token with that.
This risk is probably resolved by ensuring that the certificate is either signed by a certificate authority, but if the sender uses self-signed certificates the verifying party should NOT use the public certificate sent in the <ds:KeyInfo>
, but rather obtain the public certificate from another trusted source.
Could someone please verify or point out how I'm misunderstanding XML Digital Signatures?