Certificate & Hash checking? - security

I'm asking this question in order for be 100% sure.
link
To validate the certificate to ensure it contains the information
digitally signed by the certificate authority, the web browser
verifies the digital signature. Because the digital signature is an
encrypted hash value that was computed based on the contents of the
certificate, the web browser needs to compare hash values. The web
browser computes a hash value based on the contents of the certificate
it received. It then decrypts the digital signature to determine the
hash value that the certificate authority computed. If the two hash
values match, the web browser is assured that the certificate contains
the information that the certificate authority verified and digitally
signed.
questions :
The web browser computes a hash value based on the contents of the
certificate it received
The browser knows in which digest algorithm the certificate was used inside , so he uses it also to calculate a hash - based on the certificate content.
It then decrypts the digital signature to determine the hash value
that the certificate authority computed
The browser knows which CA created the certificate , so he takes the public key from the appropriate computer store location and apply it on the encrypted hash value . the result is the decrypted hash value.
It then see if both the same.
Am I right ?

(You may be interested in this question on Security.SE.)
This is the structure of an X.509 certificate:
Certificate ::= SEQUENCE {
tbsCertificate TBSCertificate,
signatureAlgorithm AlgorithmIdentifier,
signatureValue BIT STRING }
TBSCertificate ::= SEQUENCE {
version [0] EXPLICIT Version DEFAULT v1,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
validity Validity,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
-- If present, version MUST be v2 or v3
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
-- If present, version MUST be v2 or v3
extensions [3] EXPLICIT Extensions OPTIONAL
-- If present, version MUST be v3
}
When presented with the certificate, the browser gets the signature algorithm from the certificate itself. Typically, this is something like RSAwithSHA1.
In this case, it can indeed recalculate the SHA-1 digest of the TBSCertificate (the actual content of the certificate).
In addition, from the TBSCertificate, it can find the issuer name: this is what's used to find a trust anchor from the known CA certificates (the issuer name must match the subject of the CA certificate). When it has found the CA certificate with the right name in the list it already trusts, it can get the public RSA key from that CA certificate.
Having both the SHA-1 digest and the RSA public key, it can verify that the signatureValue matches.
the digital signature is an encrypted hash value
That's not strictly true, although it's commonly said. Digital signatures are digital signatures, not encryption.
The problem is that RSA uses the same maths to encrypt and sign: encryption with the public key and signature with the private key. Often, one is confused with the other (even in the OpenSSL API). It doesn't make sense to "encrypt" with a private key, since "encrypting" implies hiding (and you're not hiding anything if you're giving the public key away so the it can "decrypt" the signature).
This subtly about hash and encryption with digital signatures wouldn't work with some other algorithms such as DSA, which are for signatures only.
This is why a number of digital signature APIs combine the hash and key usage into a single "sign" or "verify" operation. This is what the Java Signature API does, for example: you tell it to use RSAwithSHA1 or DSAwithSHA1, give it the key and the message, and tell it to sign or verify, you don't have to do the digest or "encryption" manually.
For the purpose of certificate verification: the browser gets the issuer from the cert and find the corresponding public key (from trusted CA certs), it also gets the signature algorithm from the cert, and then verifies the signature with that public key and the TBSCertificate content, according to what the signature algorithm dictates.

Related

How a client(web browser) use public key on CA certificate to authenticate digital signature on server certificate?

While studying how https works, ssl handshake in https, following points were raised without getting complete answer.
In the flow of https, how client upon receiving server certificate validates its authenticity using digital signature in server certificate and public key of CA certificate.
May anyone explain this in brief?
In brief the idea of asymmetric cryptography is that you can encrypt with one key and decrypt with another key. The idea of digital signature is that you can encrypt with private key and decrypt with public key.
So when CA issues certificate for server it encodes some fields of certificate (described in specification):
TBSCertificate ::= SEQUENCE {
version [0] EXPLICIT Version DEFAULT v1,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
validity Validity,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
-- If present, version MUST be v2 or v3
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
-- If present, version MUST be v2 or v3
extensions [3] EXPLICIT Extensions OPTIONAL
-- If present, version MUST be v3
}
in DER format and then encrypts it with its private key using signatureAlgorithm. When browser receives server certificate it takes the same fields in DER format then it takes CA public key and decrypts the encrypted signature of certificate using signatureAlgorithm.
If they match, that means that the certificate was really signed by CA and it can be trusted.

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!

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)

What is the difference between the x.509 V3 extensions Basic Constraints and Key Usage to create a CA certificate?

These two actions seem to do the same:
using the Basic Constraints extension in a X.509 Certificate to signify that it is a CA certificate and
using the Key Usage extension e.g. to signify that the public key can be used for certificate signining.
What is the difference between these extensions?
Do they serve same purpose or complement each other?
"Key Usage" defines what can be done with the key contained in the certificate. Examples of usage are: ciphering, signature, signing certificates, signing CRLs.
"Basic Constraints" identifies if the subject of certificates is a CA who is allowed to issue child certificates.
For a certificate that can be used to sign certificates, the info is in some sense duplicated:
X509v3 Basic Constraints: CA: TRUE --- Can sign certificates
X509v3 Key Usage: Key Cert Sign --- Can sign certificates
But "Basic Constraints" will also specify the maximum depth of valid certification chain.
Though it is duplicated, you need to specify both, according to RFC 3280 --- X.509.
This is the relevant paragraph from the RFC (page 29):
The keyCertSign bit is asserted when the subject public key is
used for verifying a signature on public key certificates. If the
keyCertSign bit is asserted, then the cA bit in the basic
constraints extension (section 4.2.1.10) MUST also be asserted.
Key Usage describes intended purposes of the certificate.
Basic Constraints extension describes how deep the certificate chain that has the certificate as it's top can be. In other words, this extension is used by CAs to restrict activity of their sub-CAs when the sub-CA certificate is issued. If toplevel CA gets a sub-CA , it allows sub-CA to issue end-user certificates, but doesn't allow sub-CA have it's own sub-CAs.

Resources