Share Public Key between two devices over network [RSA] - encryption

I am working with Asymmetric Cryptography (RSA & ECC). I have a very fundamental question when it comes to public key exchange or at least my understanding of the mechanism.
Considerations
client called C1
server called S1
algorithm: RSA (asymmetric)
threat: Man in the Middle
objective: transfer of sensitive information over the network (can be data or symmetric keys for hybrid encription)
What I've read so far
C1 creates a pair of RSA keys and makes an API call sending in the public key to S1.
On getting a request with the client's public key the server (S1) generates a RSA key pair and sends it back to the client (C1).
Now that the key's have now been transferred, C1 encrypts the data (cipher text) using the server's public key, sign's the cipher text with client's private key and makes an API call.
The server receives the request that contains the cipher text, uses the client's public key to validate signature, uses the server private key to decrypt the data, performs some operations, generates the response, encrypts the response using the client's public key, signs the response cipher text with server private key and returns the response.
How can the Man in The Middle Attack is possible?
in the initial call, let's say the hacker intercepts the first call that the client (C1) makes, generates a RSA key pair and sends the server the Hacker's public key instead.
The server returns back the server public key and the hacker intercepts the server response and stores the server's public key and then returns hacker's public key to the client.
The client assumes the Hacker's public key is in fact the server's public key, encrypts the data, signs it and sends it back.
The hacker intercepts that call as well and it decrypts the data, modifies it and encrypts it with the server public key, signs it with Hacker's private key and sends it to the server.
The server verifies the cipher text and tries to decrypt it and it all works since the server has hacker's public registered as the client's public key.
Now this out to be very easy to crack, the hacker (Man in the Middle) can read sensitive information and can also modify the request that can lead to malicious operations on the application server.
I am sure I am missing something in this flow since RSA and such interaction is so widely used. Can someone please point out what have I missed and if I haven't missed out anything, how can I protect the system against such attacks

Related

how client sending client's public key to server?

as of my research on google, i got that rsa works on this way.
A client (for example browser) sends its public key to the server and requests for some data.
The server encrypts the data using client’s public key and sends the encrypted data.
Client receives this data and decrypts it
my question is, since we are communicating over https, everything should be encrypted. but how browser sending client's public key?
is it encrypted? cause server never shared servers public key to client (in order to encrypt public key of client)
how the 1st step happeningn-> (1. A client (for example browser) sends its public key to the server and requests for some data.)
thank you in advance.
Since the public keys are public, we don't need to encrypt it. it is okay to send public key in plain text. even a third party get your public key, they cannot decrypt the data which is encrypted with public key by the server.

Encrypted SAML Assertion

Based on my reading, we use both the certificate and a public key to encrypt the assertion, and to decrypt the assertion, we have to use the private key to decrypt it. I do not want to share my private key with my client, Is there other way to not provide the private key? I want to keep the private key, encrypt my assertion and give the response to my client, the client will use the public key instead to decrypt my message, does this thinking work at all?
Thank you.
The private key is just a very long number and is used to decrypt. The public key is just a very long number and is used to encrypt. Only the corresponding private key can decrypt what a public key encrypts.
A certificate (X509 public certificate) wraps the public key and the private key in identity information. The certificate is digitally signed by a certificate authority to say, to the best of its knowledge that the key belongs to who it says it belongs to.
You give your public key to your client. They verify it's from you by checking the digital signature on its certificate and they encrypt information with your public key.
You then decrypt that information using the corresponding private key which you never ever give to anyone.
It's all about Public Key Infrastructure (PKI).
I want to keep the private key, encrypt my assertion and give the response to my client, the client will use the public key instead to decrypt my message
From the text I assume you're implementing a SAML IdP.
Actually you need the client's SP public key to encrypt the assertion for the SP. And then sign the assertions with your (IdP) private key.
The SP must validate the SAML assertion signature with the IdP's public key and then they may decrypt the assertions with their SP private key.
So indeed the private keys stay with their owners.

Information to be kept for non-repudiation?

I'm using Java applet to sign XML files in a web browser.
what information, in addition to X509 key which is included in signed XML, should I keep to ensure non-repudiation?
I have seen applets transferring private key (encrypted using same private key) or just public key.
In XMLDsig/XAdES signature, the non-repudiation (proof of the integrity and origin of data) is provided by the signature itself.
The integrity is provided because if you change any bytes of the signature you will broke it (the signature can't validate), and the origin of data is provided by the <xmldsig:keyInfo> element which provides you the necessary certificate to validate the signature (however this element it's optional, so if it's not present it's supposed that application context it's enough to get that certificate), if the signature validate with this certificate you've the identity of the signature author. Besides in XAdES standard is defined the <xades:SigningCertificate> attribute which is mandatory and also it references the necessary certificate to validate the signature.
Hope this helps,
You should never transfer a private key except possibly for backup. The safest method of keeping a private key safe is to create a key pair at the location where the private key is required and then transfer the public key using a certificate request.
To verify and validate a certificate, and therefore a signature, you need the following things:
A chain of certificates that starts with the certificate of the key pair used for the signature, up to some trusted certificate. The chain can exist of 1 self signed certificate, but usually it's longer. Usually you trust some root certificate, have 1 or 2 CA certificates, ending with the leaf certificate that performs the signing.
Some method of verifying that any of the certificates in the chain was not revoked. Usually this is a frequently distributed CRL or OCSP.
A clock. Without a trusted clock it is not possibly to verify if the certificate has expire.
These are all required for verification. For signing, you don't have to keep anything. Of course, you normally hold on to your private key and certificate.

X.509 Self Signed Certificates

I'm trying to understand more about X.509 Digital Certificates. There seems to be lots of contradiction around. I am using Bouncy Castle to generate a key pair, using
public static void SaveToFile(X509Certificate newCert, AsymmetricCipherKeyPair kp, string filePath, string certAlias, string password)
{
var newStore = new Pkcs12Store();
var certEntry = new X509CertificateEntry(newCert);
newStore.SetCertificateEntry(certAlias, certEntry);
newStore.SetKeyEntry(certAlias,
new AsymmetricKeyEntry(kp.Private), new[] { certEntry });
using (var certFile = File.Create(filePath))
newStore.Save(certFile, password.ToCharArray(), new SecureRandom(new CryptoApiRandomGenerator()));
}
This saves the generated certificate to disk. Some articles tell us there is no need to password protect the certificate as there is no PRIVATE KEY stored in there. Then this article says the certificate does indeed contain the PRIVATE KEY.
I guess I have two questions that will hopefully help me understand this:
If I generate my keys in this way, should the password be the SAME as the passphrase for the PRIVATE KEY?
Do I distribute the X.509 certificate to prove the PUBLIC KEY is mine (being paired to my name in the certificate) or should the certificate be kept as safe and secret as the PRIVATE KEY and what use is a self-signed certificate?
A PKCS#12 file can contain both the certificate and the private key. They are, however, stored as separate, distinct objects. The certificate itself has the public key embedded within it. Since the certificate only contains the public key, it is considered "public" as well. You can feel free to distribute the certificate, as it does not contain the private key, which should be kept confidential. This is the basis of the security in asymmetric cryptography.
Because a PKCS#12 file contains both items, it is encrypted with a password to protect the private key within it. That said, you would use the private key to prove that the certificate you distribute belongs to you. For example, through the use of a digital signature on a document.
Hope that helps!
Certificate is actually the block of information which binds your identity (i.e. your name, email, whatever else) to some public key. It is public so everyone can know that this key belongs to you.
So when you will sign something they will know that actually you signed this.
The other thing is validating certificate - that's for what trusted root certificates are used.
Private key is your own secret information, and MUST be kept secret.

Passing signature public key along with the signature

Can anybody explain me a sense of passing a public key along with signature which is practiced in SAML 2.0? As I know signature is needed to make sure the message was not intercepted by someone, so I need to make sure the public key I'm validating the signature with is pertained to the sender, which in case of in SAML 2.0 I can get with metadata beforehand. However if I take a public key from the message in run-time, how can I know it is not intercepted and other interceptor's public key is included?
You not only want to validate that the public key matches the signature, you also want to validate that the public key itself is valid. This is generally done through a certificate chain, where each certificate in the chain is basically a signed public key. You need to ensure that each certificate is valid (has not expired, has not been revoked) and that you trust the signers of each certificate. Be careful who you trust and pay attention to revocation.

Resources