There is no easy way to do this, which is why in practice it is used certificates and not simple pairs of keys. A certificate is:
- A public key...
- Associated with a identity (a name)...
- And both signed by someone trustworthy.
Let’s just say Alice and Bob know each other, but they never exchanged cryptographic keys with each other. At a certain point, someone claiming to be Bob tries to initiate a communication, showing a public key that he claims is Bob’s. Alice has no way of knowing whether or not that key is Bob’s, unless she uses a back channel to confirm this fact (e.g.: calling Bob and asking him to say "fingerprint" - fingerprint - of the key; assuming of course that no one can tap the phone and imitate Bob’s voice...).
Fortunately, both Alice and Bob know Charlie, and both have already exchanged keys with Charlie. One way for Bob to prove to Alice that he and even Bob is by asking Charlie to confirm it to Alice. For example, sending a secure message to Alice where Bob’s key is attached. This even works, but it’s very impractical. A better option is to join Bob’s key with the name "Bob" and ask Charlie to sign it using his private key*. Charlie knows Bob’s key, and knows that it belongs to Bob, so he can sign it without any problems. Bob can then send that for Alice, and Alice - knowing Charlie’s public key - checks the signature and confirms that the key received from Bob actually belongs to him.
In that case, Charlie would be acting like a trusted third (Trusted third-party): If Charlie lies to Alice by signing a certificate that does not belong to Bob (e.g., the name "Bob" associated with Mallory’s public key), she is not at first as Alice knows, and she would be vulnerable to a Mitm. That’s why it’s important for Alice to rely heavily on Charlie, not only on his integrity but on his ability to correctly identify someone before signing his key, and to safely store those keys.
This is difficult to guarantee on a large scale, as it would require everyone to be quite a lot careful with all these aspects. For this reason, in most practical uses one chooses not to let anyone sign third-party certificates (Web of Trust), but rather concentrate on a few organizations, called Autoridades Certificadoras (Certificate Authority - CA). Steps are taken to make everyone aware of the public keys of these Cas (for example, by distributing them in the Operating System itself), and it is required that all who want a certificate hire one of them to verify their identity and sign their key.
This system is not perfect (it is sufficient for a CA to have its private key compromised so that someone can act on behalf of anyone else) but it is the one that is most used nowadays (see "Public Key Infrastructure" - Public-key Infrastructure - PKI), for example when using browser to visit a site that has never been visited before - the certificate contains the domain name, a public key, and both signed by a recognized CA. In the context of a end-to-end, it may be undesirable to have to rely on a third party to verify the identity of participants, but the only viable alternative would be to exchange those keys in person and/or use an alternative communications channel to assist in validation. Both very impractical, unfortunately...
*Note: I said "key" to simplify, but in practice you should not use the same RSA key either to sign or to encrypt - are necessary two key pairs per participant to conduct secure communication using this algorithm.
Diffie-Hellman algorithm?
– epx