How is the digital signature of a self signed certificate verified? - digital-signature

I am getting my hands dirty with https, ssl, PKI stuff. And there is one thing that I dont quite understand with self signed certificates.
Say I want to create a self-signed certificate and send it over to my friend whenever we want to establish a secure connection.
So the steps are:
create a private key.
create a public key.
sign the certificate with my public key.
So when my friend gets my certificate he has to verify that the certificate he gets is mine, he needs to decrypt digital signature. But in order to decrypt it and verify he has to have my private key. So, I am a bit confused here.

You've got things reversed. You sign with your private key that only you have.
You include your public key with the signature so the recipient can "verify" that the signature was calculated correctly.
But a self-signed certificate gives no assurance of the sender's identity since there is no way to independently verify that the signed data/document came from the supposed signer.

Related

How SSL Certificates (CA) are validated exactly?

I am searching the algorithm about how SSL validation process is performed, but almost everywhere, they explain the certificate validation step as "certificate is checked by client" or something like that, but I wonder what is the scenario behind this.
What I know is:
When the client receives a copy of the certificate that belongs to which website/server you wanna attempt to handshake, there are some indicators that shows the public information of webserver (I think this is for matching the entries in your cached certificate entries, which your browser has installed.)
Once the client matchs a cached-certificate with the webserver's one, it starts validating it. It uses the public key of cached-certificate to decrypt the signature of webserver's one.(? [Not sure this because public keys are used to "encrypt" the data, not decrypt. Also this step may be totally wrong.])
Once it decrypts, it compares the signature between cached one and webserver's one. If it is same, certificate is valid.
I also heard about chains. I really wonder how a chain is known, and how to determine if the webserver's certificate just belongs to a chain.(?)
How SSL certificates are checked by client? I need the answer as step by step and clarified. Thanks :)
Edit:
I think the public key here is used for "decrypting" instead of "encrypting". So a public key is not responsible for encrypting everytime, it can also decrypt and don't encrypt some data. The magic here is that since the public key decrypts here, if you want to fake the certificate, you should have that CA's private key to apply the changes as encrypted (because only private key can encrypt the data). But now, another question comes... What if we decrypt it using webserver's public key, then change the entries in the signature, then encrypt it again using our own private key (we generate it manually, it doesn't belong to server.), which actually make us behave like a CA; and finally overwrite the certificate to hold our own public key which is able to decrypt the data encrypted with our own private key?
There is differences between Encryption and Signature.
Public Key is used by the client to encrypt data that only the server can decrypt with the Private Key of the server.
Public Key is used by the client to verify the signature of the data send by the Server that can only be signed by the Private Key of the server.
When the client wants to access a server, the server send you a certificate containing a public key. The client usually the web browser will check in his integrated CA's list certificates if it contains it.
If it contains it, the client continue and get the CA(Certificate authority)'s that authorized this certificate.
If it not found but the verification of the signature pass, the client will get a warning saying that the certificate is probably self signed and can be malicious.
If the client can't verify the signature, it means the certificate is not valid.
for the chain of trust you can check wikipedia :
https://en.wikipedia.org/wiki/Chain_of_trust
you need to be in this chain of trust to be register in the web broswer integrated "database" of CA's.
Hope it answers your question, best regards,
M
Put it simple:
Private Key -> Decrypt and Sign
Public Key -> Encrypt and Verify
Certification Authority
Is the authority that signs and guarantees the authenticity of the certification. If you trust the CA, then you trust also its certificates.
It's the same for friends: if you have a friend that you trust and this tells you "I have a friend that I trust", then you also trust the friend of your friend.
Chain of Certificate Authority.
You can have multiple intermediate CA, for example, you can have
Root Certification Authority
Intermediate Certification Authority for WebServer signed by Root Certification Authority
Web Server Certificate signed by Intermediate Certification Authority for WebServer
Intermediate Certification Authority for signing code, signed by Root Certification Authority
Etc
Why?
Because in case one of the intermediate authorities is compromised you can revoke only its child certificates.
At the enterprise level, each CA has a different level of security, for example, the Root Certification Authority can be stored inside a safe and used only when there are two o more admins.
For the intermediate, instead, maybe only one Admin can manage it.
References
How SSL Works
How HTTPS Works
Wht digital certificates

SSL Certificate validation

I would like to know what are the exact steps of certificate authentication over HTTP.
I know this has been asked before, but from what I've read it's still unclear to me how it works.
When first contacting the secure site client will send its certificate
This will be his public key ( let's say a public_key.pem file begginging with ----BEGIN PUBLIC KEY---- )
Server will look whether this certificate has been signed by a trusted CA.
The server only has a list of certificates which it trusts (you configure this keystore when configuring SSL). That is where all private keys are stored. Is this equivalent to all the trusted CAs of the server?
The next step now is to take the public_key.pem and check whether any of the certificates in the keystore have signed it.
If the above process is accurate:
First question: A 'certificate' is a private key signed by another certificate ( or self-signed )
Second question: How exactly does a server validate that a public key was signed with a specific private key ( certificate ) ?
Third question: 'certificate' A can be used to sign another 'certificate' B, consequently 'certificate' B can be used to sign certificate C and so on. If my server has certificate A in its truststore, it means it will also trust public keys coming from certificate B and C ?
Edit based on answer below
My server has cert.pem and privkey.pem. The cert.pem ( x509 certificate ) has been signed by a trusted CA using its private key ( the 'signing' process involves the CA to do 'something' with its private key and sign my Certificate signing request ).
When SSL is negotiatied my server will send the cert.pem to the client ( in some form ). How does the client determine that my public cert was signed by a trusted CA. My truststore pb only contains other public certificates of trusted CAs, so it ends up checking whether my cert.pem was signed using only public certificates of trusted CAs.
This is is the part which is unclear - and I may be missunderstanding the whole process - can a client check if my x509 certificate is valid by just having an x509 list of certificates of trusted CAs?
When first contacting the secure site client will send its certificate
A client doesn't have to send a certificate. Judging from your question, it doesn't sound like you're asking specifically about client-cerificate authentication. In many sites, like if you go to google, stackoverflow, facebook, etc, the client / browser will not send a certificate.
A 'certificate' is a private key signed by another certificate ( or self-signed )
Not quite. A certificate contains a public key that is signed by the private key that corresponds to another certificate.
I think this is worth clearing up. A certificate itself will only ever contain the public key, or the "Subject Public Key Info" in x509 parlance. There is a corresponding private key to that public key that is stored separately from the x509 certificate.
There are some formats that "combine" the certificate and the private key in to a single file, but at this point it isn't a certificate anymore, it's a file containing a certificate - an example of this is PKCS#12. This is a format that can store as many certificates and private keys as needed.
A private key may not even necessarily be a file on disk - it could be in a Hardware Security Module, SmartCard, etc.
'certificate' A can be used to sign another 'certificate' B, consequently 'certificate' B can be used to sign certificate C and so on. If my server has certificate A in its truststore, it means it will also trust public keys coming from certificate B and C ?
Yes. This is called a certificate chain. A is the "root" certificate, B is an "intermediate", and C would be an "end-entity" or "leaf" certificate.
This is very common among HTTPS certificates by CAs. Certificates are never issued directly off the root, they're issued off the intermediate.
How exactly does a server validate that a public key was signed with a specific private key ( certificate ) ?
Well this makes the assumption that a certificate is a private key, which it isn't.
The server, as in the thing serving HTTPS, doesn't really care about the validity of the certificate. It's up to the client to decide if it should trust the certificate the server gives.
The server has the certificate and the corresponding private key. The server can validate that the public key and the private key belong together. How this is done depends on the key type, but the gist of it is, if you know the private key, you can fully reconstruct the public key from it. The server will validate that the private key's "public parts" match the certificate's public key.
The server will present the certificate to the client, like a browser. The browser will check many things, but at minimum it will check two important things:
Can the browser build a chain back to a certificate in the trust store. So the browser will look at the signer of the certificate, called the Issuer, and check if the issuer is in it's trust store. If yes, then the certificate is trusted. If no, it will see if that certificate has an Issuer, and loop all the way down the chain until it reaches the end of the chain, or when it finds something in the trust store. If it reaches the end, then the certificate was not issued by anyone it trusts.
That the certificate is valid for that domain. The certificate contains a Subject Alternative Name (SAN) which indicates what domains the certificate is valid for.
There are lots of other things that get checked, like expiration, revocation, Certificate Transparency, "strength" of the certificate - too many to list.
How does the client determine that my public cert was signed by a trusted CA.
Every client has its own trust store. Internet Explorer on Windows uses the Windows trust store, Google Chrome on macOS and Windows use the operating system trust store (Keychain, Windows Trust Store, etc).
The browser / client needs to build a trust path, as described above. How it does this is a bit complex, but it works out to the Authority Key ID attribute - if it exists, and the Issuer property of the certificate. It uses these values to find the certificate that issued it.
Once it finds the issuing certificate, it checks the signature on the certificate with the issuer's certificate public key.
That issuing certificate could be in the "root" trust store, and uses the public key in the issuing certificate to verify the signed certificate.
Your web server might (probably) send intermediate certificates along with the "main" (leaf) certificate. The client might use these intermediates to build a path back to a certificate that is in the root trust store. Intermediates can only be used as intermediates - you can't send an additional certificate saying "here's the root certificate, trust it".
can a client check if my x509 certificate is valid by just having an x509 list of certificates of trusted CAs?
Yes. That is the trust store. Every browser has / uses one. Firefox has their own trust store called NSS. Operating systems typically have their own trust store, too.

JWT RS256: Is it safe to fetch public key over https?

I'm signing JWT's using the RS256 algorithm. To verify those tokens on the client, I somehow need to access the public key.
Are there security concerns (spoofing, ...) when I set up an unprotected API route ('/api/certificate') that returns the certificate containing the public key. And do I need to take any extra security measurements?
Several concepts are often mixed up, maybe not for you, but let me try to explain a few things in this answer.
Assymetric cryptography obviously needs a public and a private key, both are basically just numbers. The private key is kept secret, the public is, well, public, anybody can have it. When signing stuff, you use the private key to sign and then anybody can verify using the public key that the signature was made by somebody that had the corresponding private key (ie. you).
But the question is then how you distribute your public key, or in your jwt example, how clients get it. As you correctly pointed out in the question, simply downloading the public key over an insecure channel is not good enough as an attacker could replace it with his own, resulting in the attacker being able to sign tokens.
One solution to this could be getting it over https as you proposed, which practically means using a second set of public-private keypair (keys of the webserver) to secure sending the first one. The theoretical question is still the same btw, it's just inherently solved in the background for you: how does the browser know that the public key it receives from the server upon connection actually belongs to the server. There is no secure channel yet between them.
Enter certificates.
A certificate is a document that essentially ties a public key to its owner, and that is excactly what you want. When a browser connects to a website, the server sends its public key along with its certificate, so that the browser can verify that the public key actually belongs to the server (the domain name in this case) that sent it. How that verifies it is beyond the scope of this post, the point is that the certificate is signed by another public key, the certificate to which may be signed by another public key, etc., and the chain is terminated by a list of so called trusted root certificates already set up for your computer and/or browser by your OS/browser vendor.
And you too should verify the public key with the certificate the same way. You don't even need the burden of SSL (https) transport for this, verifying that a public key belongs to a particular subject is the main purpose of certificates.
So all you have to do is not just get the public key from the API, but get it along with its certificate. You are probably already doing this, bare public keys are very rarely used. You are most probably already receiving a pfx or cer or crt or whatever from the server. Depending on the technology stack that you are developing on, you can for sure use built in mechanisms to fully verify a certificate and make sure it's valid. Please don't implement your own validation though, as that's tricky business and quite hard to get right. If the certificate passes validation, you can trust that the public key you received from the API is authentic and belongs to whatever it claims to belong to. There may be caveats though (like for example make sure that beyond basic validation, you check a combination of fields from the certificate that others can't have).
As an additional security measure, you can also implement certificate pinning to make it even more secure against certain types of attacks by having a list of fingerprints for valid certificates in the client (less so in a browser client, but still the concept is the same).
Edit (what fields to check in the certificate after it passed general validation of expiry, etc):
In the general case it depends on who signed the certificate and what kind of certificate it is.
A server certificate signed by a real certificate authority (CA) can only have the server domain as its common name (CN) field, a real CA won't normally sign anything else, and they also won't sign a certificate for yourdomain.com unless you can prove you control yourdomain.com. So in this case it may be enough to check CN after the cert passed validation. You do need to check CN though, as anybody can have a valid certificate from say GlobalSign or Thawte or other trusted CAs, it just costs money. What they can't have is a certificate for yourdomain.com.
If you sign your own certificates, you also won't sign anything for anyone, so in that case it could be enough to check the issuer (that you signed it) and the CN (for whom). If the certificate otherwise passed validation (meaning a trusted root certificate signed it) it should be ok, as an attacker won't normally be able to have his CA certificate as trusted on your computer.
The point in general is that you want to check something that others can't have. It's easier, if you are relying on real CAs, and it's usually best to check the fingerprint.

Why certificate is needed for signing instead of just private/public key pair?

Newbie question: some vendors propose solution like generating dynamic certificates to allow user who haven't classic certificate to sign documents. But why not just generate private/public keys alone instead of bothering with certificate format ?
The purpose of the (public key) certificate is to bind the public key to the identity of its subject (i.e. the owner/entity associated with the key pair), and possibly various attributes telling you what the certificate may be used for. (You may be interested in this question on Security.SE.)
You always sign with the private key (not the public key or the certificate), but the public key or certificate are often attached with the signed document.
If you have an explicit list of public keys you know and can link independently to a user, you don't need a certificate.
The certificate allows third parties (who have signed the certificate) to assert the binding between the identifier and the public key. Even if you don't know that identity in advance, you can link the signature to the signer's identity as long as you trust the entity that signed the certificate.
Dynamically generated certificates may not be very useful in this case, unless you trust the party that generates the certificate dynamically (I'm not sure if you meant the tool itself or perhaps a website that you would also know).
Often, X.509 certificates will be used just to attach to that signature, because the tooling requires it, whereas you may be able to match the public key against an identity you know directly in the tool with which you verify the signature. Sometimes, it's also just done in anticipation of a case where it will be useful one day.
For example, if you publish your own artifacts to the central Maven repository, you will be required to sign it with your PGP certificate (often only referred to as the PGP public key). Yet, no verification of the certificate is made at all during the process (PGP certificate with only its self-signed signature is good enough). This makes this process relatively pointless in this case, but makes it possible to be stricter in which artifacts you want to use, if you're able to verify those certificates later on.
It's the same but you need a third party to consent that private key belongs to whom ever you think it belongs to.
Signing proves first of all authorship (or approval) of the document by some person. And the key alone won't prove anything. This is what the certificate is needed for - some certificate authority signs the certificate of the user and certifies that the keypair belongs to the person (or legal entity) to which the certificate is issued. The reader of the document can ensure that the signature is valid not by just computing the signature itself, but also by validating the certificate and seeing the name of the certificate owner.
I don't quite understand what vendors can issue certificates dynamically - issuing certificate in such way that they are not self-signed (and self-signed certificates make little sense in context of document signing) requires that the private key, used for signing the certificate, should be embedded into software of those vendors, and as such it's also prone to misuse.

can Digital certificate signature be copied? (ssl)

According to X.509 standard private key signature has to generate same encrypted message for ever?Am I right?
In order to avoid coping which data field in digital certificate will be changed?
they can't process the information of the user, but by coping the digital signature generated by private key and keeping along with the webpage attacker can say that I am certified by the CA and web browser will agree with that information.Is it true?
Version number,Serial number,Certificate algorithm identifier,Issuer name,Validity period,Subject name,Subject public key information Issuer unique identifier,Subject unique identifier,Extensions,Certification authority's digital signature.
These are the fields in digital certificate,if this fields don't change for ever,encrypted value will be same for ever.If I go to gmail it sends Encrypted digital certificate.If I use that Encrypted digital certificate in my webpage cant I say I am owner of gmail.but I can't use information send by the user since I won't have private key
A certificate must be signed by a CA in order to be considered as valid. The contents of the certificate is hashed, then encrypted by the CA's private key. Anyone can then validate whether the certificate is valid by decrypting the signature with the CA's public key, and verifying whether the hash matches.
The signature verifies that a particular name is associated with a particular public key - even if someone copied the certificate file verbatim, they wouldn't know the private key corresponding to that public key, and so they couldn't use it to impersonate the owner of the certificate.
I was wondering the same question.
Reading #Anon.'s answer led me to this: https://en.wikipedia.org/wiki/Transport_Layer_Security#Description
The handshake begins when a client connects to a TLS-enabled server
requesting a secure connection and the client presents a list of
supported cipher suites (ciphers and hash functions).
From this list, the server picks a cipher and hash function that it
also supports and notifies the client of the decision.
The server usually then sends back its identification in the form of a
digital certificate. The certificate contains the server name, the
trusted certificate authority (CA) that vouches for the authenticity
of the certificate, and the server's public encryption key.
The client confirms the validity of the certificate before proceeding.
To generate the session keys used for the secure connection, the
client either:
encrypts a random number with the server's public key
and sends the result to the server (which only the server should be
able to decrypt with its private key); both parties then use the
random number to generate a unique session key for subsequent
encryption and decryption of data during the session or
uses Diffie-Hellman key exchange to securely generate a random and unique
session key for encryption and decryption that has the additional
property of forward secrecy: if the server's private key is disclosed
in future, it cannot be used to decrypt the current session, even if
the session is intercepted and recorded by a third party.
It looks like in your forgery example (that I was wondered also) the client confirms the certificate successfully in paragraph 4. And then in paragraph 5 they fail to agree on session key as the server cannot read client's random number.

Resources