If I have a web-page being sent over the Internet without encryption, anybody in the middle can change it. So if I put a public key of a server inside, the attacker can replace it with his own and decrypt the message sent by the client to the "server" (really an attacker).

How can I be sure that the communication is secure?

P.S. please don't tell me about SSL/TLS. It is all about trust to a third-party CA.

  • 3
    Yes, it's all about trust in a third party CA, that's right. You could roll your own alternative I suppose, but I wonder if that would be termed HTTP? – Peter David Carter Apr 28 '20 at 15:41
  • 3
    @iam Are you willing to consider out-of-band communication? For example, whenever I visit your website, I use a special key to decrypt the content that you personally handed to me in real life? – Fire Quacker Apr 28 '20 at 15:41
  • 4
    Trusting a 3rd party is the solution to this problem. Either a 3rd party channel, a 3rd party that signs the keys, or a 3rd party for authentication. – schroeder Apr 28 '20 at 15:43
  • 2
    @Machavity not a dupe. This question is about "how" not "whether" – schroeder Apr 28 '20 at 15:48
  • 4
    There's no inherent reason there needs to be a third party source of trust. You can trust a key handed to you directly by the party you want to communicate with, in advance. And the right way to do this is still HTTPS/TLS. You just ignore the webpki mess and use the key. – R.. GitHub STOP HELPING ICE Apr 29 '20 at 0:19

P.S. please don't tell me about SSL/TLS.

TLS is the solution. It ensures that you are talking with the holder of the private key corresponding to the certificate. It's made for this purpose. It's tested for this purpose. It's built explicitly to withstand MiTM-attacks.

If you distribute certificates ahead of time, you can ensure that there's no man in the middle with TLS. The CA-infrastructure is basically this distribution.

It is all about trust to a third-party CA.

Then don't use a thirdparty CA - roll your own, and take the pains of distributing certificates manually.

Or roll with HPKP, which basically validates that the public key (and thus the private key) has not changed, which means a fraudulent CA can't replace the certificate.

  • 5
    Also consider no certificates, en.m.wikipedia.org/wiki/TLS-SRP – multithr3at3d Apr 28 '20 at 17:48
  • 2
    Alternatively you can distribute the key fingerprint via DANE. Existing browsers won't use this because they're dragging their feet over it (and some are deeply committed to the CA/webpki system), but if you're implementing the client you can validate it. – R.. GitHub STOP HELPING ICE Apr 29 '20 at 0:17
  • @R..GitHubSTOPHELPINGICE With DANE the trust-relationship gets shifted from the CAs to the DNS servers. You are still trusting a 3rd party. This is especially problematic, because TLS with root CAs is the thing that stops rogue DNS from redirecting people to fake websites. – Philipp Apr 29 '20 at 12:40
  • @philipp: No, you never trust rogue nameservers because they can't produce valid signatures. You do trust a single root under normal usage (the dns root) but with webpki you already trusted it anyway because the CA issued the cert based on dns. If you want you can distrust the root and only trust your own trust anchor keys for particular domains. – R.. GitHub STOP HELPING ICE Apr 29 '20 at 13:05
  • HTTP Public Key Pinning support has been removed in every recent browser. – Jean Hominal Apr 29 '20 at 16:58

Theoretically speaking, it is not even remotely possible; an attacker can intercept the connection between the server to the client at any point in time, regardless if it was the first connection or a re-connection. That is, unless you pass the public key (or certificate) physically to the client somehow, which the public key infrastructure (PKI) technically somewhat relies upon.

There is a list of trusted certificates in your browser, called root certificates, that were shipped to your browser when you first downloaded it securely (example, downloading Chrome through Microsoft Edge) or when you bought the PC (think, installing a new laptop with Windows). These browser root certificates are then used to verify intermediate certificates, which ultimately, verifies a website's certificate. That's how you can be sure a website's certificate is valid (because it ultimately places trust on the initial transmission of the root certificate!).

That said, there is something called a supply chain attack, where the attacker modifies the list of root certificate at the time of manufacture (example, shipping a Windows installation disc with an ill-intended root certificate). The attacker can intercept your traffic with a website (or server) while the browser thinks its legit!


SSL/TLS is much more than "trusting third party CA" and in a lot of cases it is pretty much used without these "third parties".

Then again, there are two ways to prevent a MITM attack:

  1. Controlling the communication channel entirely. Easy when the "channel" is a cable on your desk, hard when the cable is behind your desk and pretty much impossible for a cable outside your building.

  2. Having a way to determine the authenticity of the messages. Here, cryptography helps. You can either use standard crypto tools or develop some yourself (good luck inventing something better than SSL/TLS or PGP and getting the other party to use it). You also HAVE TO exchange some initial data with your correspondent OR a third party trusted by both of you. You don't want third parties - OK, SSL/TLS works pretty much without them. PGP is designed to work without trusted third parties in the first place.

    Just securely exchange the keys first.


Can you do? Yes! There's a couple ways I can think of the top of my head.

Should you? Not, not even think about. Your clients will not bother verifying the page, and use the page as it is, or will not access your service at all because "it's difficult."

Hash: you have to calculate the hash of the page, and send it to the client by another media: email, sms, whatsapp, phone call. The client downloads the page, hashes it, and checks if it matches the value received. If not, the page was changed.

Digital Signature: send (out of band) your private key to the client. Sign every page, add the signature to them all. When the client downloads the pages, he must check the digital signature of every page, every resource, everything. Instruct the client to treat as tainted every single resource without a digital signature.

VPN: Every client must connect to your VPN server to be able to access your page. Troublesome, and requires the client to install special software to view your page.

SSH Tunnel: Client have to create a tunnel to your server, and access your website using the tunnel.

Encrypted ZIP file: get the page, put inside a zip file, send the password out of band. User downloads the zip, extracts it, and reads the page.

Self Signed Certificate: Create a self signed certificate, ship it to the users out of band (email, qrcode thru snail mail, on person) and instruct it to install on their browsers. Use the certificate on your server. You will not be trusting a 3rd party CA, but your users will be trusting a random person to add a custom certificate to their browsers.

Given that almost every single user will click on "I Agree" without even reading what they are agreeing to, and a lot of users never update their software because it takes time and effort, I seriously doubt the effectiveness of those workarounds.

If you don't trust the CAs that are shipped with your OS, you have no reason to trust the OS you are using, the phone you have, the TV you watch... Even the firmware on your microwave cannot be trusted...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.