use X509Certificate field in SAML assertion or an external cert file. - security

As Identity Provider we send a SAML assertion request to Service Provider and then they validate our signature in assertion using our certificate. SAML assertion contains an optional field called X509Certificate which is certificate of assertion issuer. (our certificate). My question is that from a security perspective is it better Service Provider use this field in each assertion for validating signature or use an external certificate file.

It's a very bad idea for them to only trust the public key value that is included in a signed message. Who's to say that someone couldn't just forge your EntityID and send them random SAMLResponses with some user data? The signature of the message would be valid, and they are using the key included in the message to validate the signature, right?
The benefits of offline key exchange are well known: Your SP has securely stored your public key and will always use to it validate the signature of your messages unless you instruct them otherwise (key rollover/update). If you include your certificate in the message, the SP will compare the two certificates first to ensure they match and then they should use the copy they have stored previously (assuming they match). Otherwise the message is rejected.
However, if you want an SP to trust the public key you include in your messages, the SP must be able to ensure that it is YOUR certificate that is being used. There are some smart folks at Ping Identity who have thought about this SP DSig Validation Use Case -- you can find a description of how they do this in their "Anchored Certificate" model for DSig Validation.
https://documentation.pingidentity.com/pingfederate/pf80/index.shtml#concept_digitalSigningPolicyCoordination.html

I don't really get the 11/19 answer. If you send your BinarySecurityToken (BST) in the Assertion for signature validation, and the receiver has an entry in his trust store with this public certificate, you should be good. In order for this to work:
1) The receiver must require that the assertion is signed
2) The receiver must check the signature verifying certificate in the assertion against a trust store.
3) DO NOT just trust the dn/issuer of the signer instead of using a trust store; that can be faked in a signing certificate.
If these things are followed, you have verified that the message is signed by the holder of the private key and that the assertion has not changed in flight. You then trust that holder, therefore you can proceed.
If the receiver doesn't require that an assertion is signed, anyone can send anything to the receiver.
If the receiver doesn't check a trust store for the verifying certificate, anyone can send a signed anything to the receiver.
The advantage of sending the BST in the message is that when your IdP certificate expires and you have to get a new one, the client only has to add your new certificate to his trust store instead of changing the configuration of his application.

Related

Verifying the signature of Alexa request

I am currently building a webservice that should handle Alexa voice intents. The HTTP request I get from Alexa must be verified by checking a signature, as described in the documentation (see below for excerpt).
Various info:
certificate chain file:https://s3.amazonaws.com/echo.api/echo-api-cert-5.pem
Original received signature for the above example signature:
LqhhuCKwBRVucGS1MHS2yf3jKMmpm10cuImDnK0bC8lQHLfCbMukdHhvulWH4SAypXqgAk3y81G0CRS4NIG+oLnTB3PfeHb70yS8WdSFflKd/NlTc/2Rr1c5pCdpZ9C1LtNmsa/pSafTbSt4RDhmQ8XtKVCw6twhTsebS6om6/ggom95z3m1Zi4k4SkLKRQGvq18+sJHcsADKHrLO735FQ3CNrIVfS76UMXkROlJ9oSEBa9KpqSONffdVe7DDBGTGF4CLjfoSDDBjQ1nCQ0THxljUdTZ2kp4cYn1qkXJfCPoLB2+75O6Cndf+BMP9+gWd20Rl5GV44KLY9ezwEmYpA==
Excerpt from the Alexa documentation:
Checking the Signature of the Request
Requests sent by Alexa provide the information you need to verify the
signature in the HTTP headers:
SignatureCertChainUrl Signature To validate the signature:
Verify the URL specified by the SignatureCertChainUrl header value on
the request to ensure that it matches the format used by Amazon. See
Verifying the Signature Certificate URL. Download the PEM-encoded
X.509 certificate chain that Alexa used to sign the message as
specified by the SignatureCertChainUrl header value on the request.
This chain is provided at runtime so that the certificate may be
updated periodically, so your web service should be resilient to
different URLs with different content. This certificate chain is
composed of, in order, (1) the Amazon signing certificate and (2) one
or more additional certificates that create a chain of trust to a root
certificate authority (CA) certificate. To confirm the validity of the
signing certificate, perform the following checks: The signing
certificate has not expired (examine both the Not Before and Not After
dates) The domain echo-api.amazon.com is present in the Subject
Alternative Names (SANs) section of the signing certificate All
certificates in the chain combine to create a chain of trust to a
trusted root CA certificate Once you have determined that the signing
certificate is valid, extract the public key from it. Base64-decode
the Signature header value on the request to obtain the encrypted
signature. Use the public key extracted from the signing certificate
to decrypt the encrypted signature to produce the asserted hash value.
Generate a SHA-1 hash value from the full HTTPS request body to
produce the derived hash value Compare the asserted hash value and
derived hash values to ensure that they match
Then I used the verify method in class SkillRequestSignatureVerifier provided by Alexa SDK, but it didn't work.
Which decoding way should I use to realize what it says:
Use the public key extracted from the signing certificate to decrypt
the encrypted signature to produce the asserted hash value.
And he say :
Generate a SHA-1 hash value from the full HTTPS request body to
produce the derived hash value.
But I don't find it. Please help me to solve this problem!

digital signature on any item using certificates stored in active directory

I want to know the ability to perform the signature on a data record ( Workflow item for example) using certificates Stored in Active directory.
I guess the signing operation will be : get the certificate of a user from active directory and generate a signature to sign the Data with it. ==> "how to get a certificate of a certain user?!"
and I guess the verifying operation will be : compare the public key stored in the signature , with all public keys of certificates in active directory , till finding the matching one , to guarantee it is a verified signature
Is that true please ? do i miss the implementation of CRL check ? and trusting certificate in windows Trust Store? where to save public Keys?

Does NodeJS crypto module fail verification if the RSA cert is expired?

If 'key' in the following code is an expired cert, will res always be false regardless of the signature's validity?
var verifier = crypto.createVerify("RSA-SHA1")
verifier.update(str)
var res = verifier.verify(key, signatureValue, 'base64')
In other words, does the NodeJS crypto module care about a certificate's expiration when validating a signature. This is all in the context of validating a signed XML document.
No, the expiration is not validated using the code above. If you directly use the public key instead of the signature then the algorithm doesn't even receive the end-of-validity date.
If the key in your code is not a key but a certificate then the signature verification does normally not fail either. The test to see if the certificate is valid should be performed before the signature over the data is verified.
The certificate verification and validation procedures in other words should contain the check that the certificate is in its validity period - among all the other checks. Signature verification should only take place after that.

Verifying the signature of an Alexa request

I am currently building a webservice that should handle Alexa voice intents. The HTTP request I get from Alexa must be verified by checking a signature, as described in the documentation (see below for excerpt).
I seem to correctly decrypt the signature sent in the request, and seem to correctly compute the request body's signature. But they differ - but instead of being completely different (which would hint at some error in the computation), the computed signature is a suffix of the sent signature. For example:
Received signature (decoded and decrypted):
3021300906052b0e03021a05000414ca5cc3be233b045be79e94389e47353b7aaec434
Calculated signature of the request body (its sha1 hash):
ca5cc3be233b045be79e94389e47353b7aaec434
What are the extra bytes at the beginning of the received signature? They don't seem to change between requests.
Various info:
The current (2016-10-29) certificate chain file
Original received signature for the above example signature: M4Xq8WmUHjaR4Fgj9HUheoOUkZf4tkc5koBtkBq/nCmh4X6EiimBXWa7p+kHoMx9noTdytGSUREaxYofTne1CzYOW0wxb9x6Jhor6lMwHAr4cY+aR1AEOkWrjsP94bewRr1/CxYNl7kGcj4+QjbEa/7dL19BNmLiufMLZDdRFsZSzlfXpPaAspsoStqVc/qc26tj5R9wtB0sTS4wbFc4eyCPFaCZocq1gmjfR3YQXupuD7J3slrz54SxukNmL/M1CIoZ8lOXjS82XLkKjsrzXdY5ePk8XsEDjNWkFSLbqzBzGBqzWx4M913uDA6gPx5tFKeoP8FgpV+BHKDf3d4gmQ==
Excerpt from the Alexa documentation:
Checking the Signature of the Request
Requests sent by Alexa provide the information you need to verify the signature in the HTTP headers:
SignatureCertChainUrl
Signature
To validate the signature:
Verify the URL specified by the SignatureCertChainUrl header value on the request to ensure that it matches the format used by Amazon. See Verifying the Signature Certificate URL.
Download the PEM-encoded X.509 certificate chain that Alexa used to sign the message as specified by the SignatureCertChainUrl header value on the request.
This chain is provided at runtime so that the certificate may be updated periodically, so your web service should be resilient to different URLs with different content.
This certificate chain is composed of, in order, (1) the Amazon signing certificate and (2) one or more additional certificates that create a chain of trust to a root certificate authority (CA) certificate. To confirm the validity of the signing certificate, perform the following checks:
The signing certificate has not expired (examine both the Not Before and Not After dates)
The domain echo-api.amazon.com is present in the Subject Alternative Names (SANs) section of the signing certificate
All certificates in the chain combine to create a chain of trust to a trusted root CA certificate
Once you have determined that the signing certificate is valid, extract the public key from it.
Base64-decode the Signature header value on the request to obtain the encrypted signature.
Use the public key extracted from the signing certificate to decrypt the encrypted signature to produce the asserted hash value.
Generate a SHA-1 hash value from the full HTTPS request body to produce the derived hash value
Compare the asserted hash value and derived hash values to ensure that they match
By googleing for the prefix 3021300906052b0e03021a05000414 of the sent signature I found out that the prefix is a constant that indicates the used hash algorithm. Either just cutting it off, or letting OpenSSL do the signature verification solves the problem. Never brew your own crypto!

Creating a Digital Certificate without signing it

I have created a key-pair and now I want to bind my public key with an email id (create a digital certificate). I do not want to do the next step of signing the certificate.
Question: How can I create the digital certificate (hence bind the public key with the identity) and not really sign it for now ? (Using OpenSSL for the same would be fine).
My understanding:
Digital certificate is just packaging the public key with an
identity.
Digital signature is a CA assuring/signing the
certificate and embedding the signature in the certificate file
Or is my understanding all wrong ?
Signature is a required part of certificate. You may instead create so-called self-signed certificate, signed by your own key.
if i got your question right, you want to prepare a certificate and stop the process before the actual signing by a CA would happen ...
the thing you are looking for is a so called certificate request ...
have a look at the "openssl req" command ... for examples see http://www.openssl.org/docs/apps/req.html (examples section shows generating a new request)

Resources