Digital signature man in the middle attack prevention - cryptography

I have client-side generated a digital signature(JavaScript). The signature is then verified on Java back end. To verify the signature I am passing to the backend - (signature value, public key and message for verification). So far so good, but then the question arises - What if someone performs a man in the middle attack? He can easily generate a signature and send his - (signature value, public key and message.). So in a sense, this makes my current implementation not secure enough.
How can I avoid this? As far as I researched I have to verify that the public key sent is coming from the appropriate client and this is done through CA (Certificate Authority). However, in my case, I am doing this as a final project in university and I am not sure how to approach this problem.
Should I generate the public key certificate on the client side and send them along with the public key? Is it possible to generate self-signed-certificates on client-side and then verify it on the back-end?

What if someone performs a man in the middle attack
A MITM could replace the signature and the public key
How can I avoid this?
Mainly use SSL/TLS and/or...
As far as I researched I have to verify that the public key sent is coming from the appropriate client and this is done through CA (Certificate Authority)
If you use a Certificate Authority, each certificate is signed with the private key of the root CA certificate (or a subCA), so a MITM can not create a valid certificate because he does not own the root private key.
At server side, you can validate that the signature has been performed with a private key that corresponds to a certificate issued by the CA. Note that in this case you are working with certificates, not just with public keys ( a certificate envelopes a public key).
I am doing this as a final project in university and I am not sure how to approach this problem.
You have explained your solution but not the background. I mean why do you decided you need a digital signature? without that information I can not advise you.
Should I generate the public key certificate on the client side and send them along with the public key?
Read my previous comment
Is it possible to generate self-signed-certificates on client-side and then verify it on the back-end?
Yes, of course. You can generate a key pair at client side and associate the public key with the user's account during the registration process (using a secure channel)
This way you do not even need a password. The digital signature with the private key is the authentication proof. Using a CA is optional. The CA could issue a certificate containing the public key, but fot this scenario is not required

Related

Subject Publish Key Pinning for HTTPs

I am implementing the SPKI Pinning to my mobile apps and i wonder if the Subject Publish Key will change when I renew it with another CA?
I still use the same CSR to generate the cert. People say that the Public Key will be the same if we use the same Certificate Signing Request file (CRS), But I'm not sure if CA is also a factor.
Short answer is: no, it shouldn't change, provided you did things properly.
It is recommended that when you specify a SPKI HTTP header you should provide at least two Subject Public Key Information (SPKI) fingerprint of private keys in your control (one for production and other for backup). Now, as reported here, it is a common practice to specify the SPKI fingerprint of well known CA in the case of private key loss, but it renders HPKP invalid because if the CA is compromised then you are basically saying "trust the CA issued certificates". That is why recommendation is to provide the SPKI fingerprint of your own public keys: one for common usage and another in case of private key loss.
Thus, provided you are specifying in the SPKI HTTP header of your own public key, whenever you generate a new certificate with another CA (either with the same CSR or a new one) your public key will be the same and the SPKI will still be valid.

Encrypting a file using a private key and public key

I am a developer with very little experience of encryption. I am trying to learn more about Encryption and specifically SSL in my spare time.
Say a trusted company has a file (notepad) that contains a load of personal and confidential information. Say I wanted to ask them to send this information to a me to analyze. How would I do this?
My research is telling me that I would have to:
1) Create a self signed certificate
2) Generate the public and private key
3) Issue the public key to the trusted company and keep the private key
4) Ask the company to encrypt the information using the public key and then send it to me
5) Decrypt the file using the private key
Is that correct? How would I do this?
Should the certificate be signed by a Certificate Authority in this case as I would manually be issuing the public key to the trusted company (they know it comes from me).
As I said I am relatively new to this subject.
SSL is a protocol for encrypting network connections. It's not really relevant for manually encrypting and decrypting files. (It's also insecure and deprecated; TLS should be used instead.)
If you want to manually encrypt and decrypt files, yes, you could use a self-signed certificate and just give the public key to the company that'll send the file. However, you have to make sure to give them the public key in a way that can't be intercepted — such as physically handing it over on a flash drive, not emailing it — or you're vulnerable to a man-in-the-middle attack: someone could intercept the public key and give the company a different one instead. (If that happened, the company would unknowingly be encrypting the file for the attacker to decrypt, and the attacker would then re-encrypt the file with the real public key and send it along to you.)
If you're doing this manually and you deliver the public key in a secure way, you don't need to involve a certificate authority. The purpose of a certificate authority is to vouch for the authenticity of a certificate when it's delivered over an insecure channel. For example, when you visit stackoverflow.com, your browser gets a certificate (with a public key) from the web server. Since this certificate wasn't personally given to you by SO staff, how do you know that the web server is the real stackoverflow.com, not a man-in-the-middle attacker intercepting your connection in order to hijack your account? The website's certificate is signed by a certificate authority — DigiCert, currently — that says DigiCert has verified that it's real. Your browser is configured to trust that signature from DigiCert, because the browser developers have verified that the company is trustworthy.
PGP and GPG are good tools for securely exchanging encrypted files. They use a "web-of-trust" model based on securely exchanging certificates, rather than relying on a certificate authority.

How to sign a message with my https public key certificate?

I just got myself an ssl certificate for my domain and it works fine, but I'm using the bitcoin payment protocol and I need to sign the messages with my public key before sending them but how are messages signed with an ssl certificate and what tools should I use?
EDIT
It seems what I actually need to do is sign a message using the public key of my ssl certificate issuer.
Thanks in advance :)
The protocol specification must be incorrect. Digital signatures are signed with your private key.
Your certificate needs to accompany the message, and probably be included in the signature. Use the java.security.Signature class in association with your private key, possibly loaded from your KeyStore.
You may need to purchase a signing certificate: an SSL certificate may not be strong enough for bitcoin.
A signature using a public key is completely worthless. Anyone can do it. You sign with your private key. This is legally equivalent to your signature: only you can do it, and anyone can check it by verifying it with your public key, which is why the public key must accompany the signature; and at the same time they can establish whose signature it is, via the certificate which must also accompany the signature.
Or else bitcoin is radically insecure.
Mystery solved, the message is to be signed using the bitcoin public key with the signmessage "bitcoinaddress" "message" bitcoin command.

How CSRs fit into the SSL Certificate Lifecycle

So you decide to go with a CA like VeriSign (or whoever, doesn't matter for this question). You apply for an SSL certificate from them. This CA invesitgates you to make sure the information you provided in your application is truthful and that you are who you say you are. Finally, the CA grants you an SSL certificate.
I am really confused about CSRs, what they are, who issues them, who responds to them, and where/how they fit into the scenario described above:
Certificate-Signing Request: To me this means "A request to sign a certificate." So, who makes the request? Who signs it? Why is this necessary?
When is a CSR generated? When is it acted upon? What subsequent procedures/actions does the CSR hold up (while it is in the process of being signed)?
How does the CSR fit into the scenario described above?
Thanks in advance!
The name is confusing - it's not a certificate signing request but a request for certificate. When you need to acquire a certificate from the CA, you do the following:
On the client side you generate a keypair (a public and a private key). You save the private key in a safe place, and also you (your generator software) creates a certificate request usually in PKCS#10 format (there's one more format used, which is more rare). This request is a binary ASN.1 sequence of various fields which are filled by you and your software. The request also includes your public key.
Next the certificate request is sent to the CA (usually transmitted over HTTPS). The CA handles the request by parsing it and creating a certificate with your public key embodied. Some information provided in the request (mainly your name / organization name, called Subject Name) is copied to the certificate. The certificate is signed with CA's private key.
The procedure can be automated but normally should involve human validation as you will be required to provide identification information (company documents, your documents etc).
Finally you receive a signed certificate from the CA. You can combine it with the private key or you can keep them separated.

How does a ROOT CA verify a signature?

Say when using https, browser makes a request to the server and server returns its certificate including public key and the CA signature.
At this point, browser will ask its CA to verify if the given public key really belongs to the server or not?
How is this verification done by the Root cert on the browser?
To give an example:
Say serverX obtained a certificate from CA "rootCA". Browser has a copy of rootCA locally stored. When the browser pings serverX and it replies with its public key+signature. Now the root CA will use its private key to decrypt the signature and make sure it is really serverX?
is it how it works?
Your server creates a key pair, consisting of a private and a public key. The server never gives out the private key, of course, but everyone may obtain a copy of the public key. The public key is embedded within a certificate container format (X.509). This container consists of meta information related to the wrapped key, e.g. the IP address or domain name of a server, the owner of that server, an e-mail contact address, when the key was created, how long it is valid, for which purposes it may be used for, and many other possible values.
The whole container is signed by a trusted certificate authority (= CA). The CA also has a private/public key pair. You give them your certificate, they verify that the information in the container are correct (e.g. is the contact information correct, does that certificate really belong to that server) and finally sign it with their private key. The public key of the CA needs to be installed on the user system. Most well known CA certificates are included already in the default installation of your favorite OS or browser.
When now a user connects to your server, your server uses the private key to sign some random data, packs that signed data together with its certificate (= public key + meta information) and sends everything to the client. What can the client do with that information?
First of all, it can use the public key within the certificate it just got sent to verify the signed data. Since only the owner of the private key is able to sign the data correctly in such a way that the public key can correctly verify the signature, it will know that whoever signed this piece of data, this person is also owning the private key to the received public key.
But what stops a hacker from intercepting the packet, replacing the signed data with data he signed himself using a different certificate and also replace the certificate with his own one? The answer is simply nothing.
That's why after the signed data has been verified (or before it is verified) the client verifies that the received certificate has a valid CA signature. Using the already installed public CA key, it verifies that the received public key has been signed by a known and hopefully trusted CA. A certificate that is not signed is not trusted by default. The user has to explicitly trust that certificate in his browser.
Finally it checks the information within the certificate itself. Does the IP address or domain name really match the IP address or domain name of the server the client is currently talking to? If not, something is fishy!
People may wonder: What stops a hacker from just creating his own key pair and just putting your domain name or IP address into his certificate and then have it signed by a CA? Easy answer: If he does that, no CA will sign his certificate. To get a CA signature, you must prove that you are really the owner of this IP address or domain name. The hacker is not the owner, thus he cannot prove that and thus he won't get a signature.
But what if the hacker registers his own domain, creates a certificate for that, and have that signed by a CA? This works, he will get it CA signed, it's his domain after all. However, he cannot use it for hacking your connection. If he uses this certificate, the browser will immediately see that the signed public key is for domain example.net, but it is currently talking to example.com, not the same domain, thus something is wrong again.
The server certificate is signed with the private key of the CA. The browser uses the public key of the CA to verify the signature. There is no direct communication between browser and CA.
The important point is that the browser ships with the public CA key. So the browser knows beforehand all CAs it can trust.
If you don't understand this, look up the basics of Asymmetric Cryptography and Digital Signatures.
Certs are based on using an asymmetric encryption like RSA. You have two keys, conventionally called the private and public keys. Something you encrypt with the private key can only be decrypted using the public key. (And, actually, vice versa.)
You can think of the cert as being like a passport or drivers license: it's a credential that says "this is who I am; you can trust it because it was given to me by someone (like Verisign) you trust." This is done with a "signature", which can be computed using the certificate authority's public key. If the data is what the CA got originally, you can verify the cert.
The cert contains identifying information about the owner of the cert. When you receive it, you use the combination of the key you know from your trusted authority to confirm that the certificate you received is valid, and that you can therefore infer you trust the person who issued the cert.
Your browser does not ask the CA to verify, instead it has a copy of the root certs locally stored, and it will use standard cryptographic procedure to verify that the cert really is valid.
This is why when you self sign a certificate your certificate is not valid, eventhough there technically is a CA to ask, you could off course copy the self signed CA to your computer and from then on it would trust your self signed certifications.
CACert.org has this same issue, it has valid certificates but since browsers don't have its root certs in their list their certificates generate warnings until the users download the root CA's and add them to their browser.