1

When SSL pinning is not available, for example when using a free TLS certificate from a CDN provider (Cloudflare - does not support HTTP public key pinning, what can be used to encrypt sensitive information?

I am solely trying to prevent Man-in-the-Middle attacks in cases where the TLS/SSL can be bypassed.

This is mainly to secure an API that will be consumed by a mobile API and also via web. We have had advice from pen tests that suggest encrypting sensitive information like Personally-Identifying Information (PII) & (PCI DSS).

I found this article (https://developer.mastercard.com/platform/documentation/security-and-authentication/securing-sensitive-data-using-payload-encryption/), by sharing a public key and then forcing browser/apps to encrypt using that public key looks like a good start, what about this flow:

  1. the API backend shares public key /api/pub.key
  2. client creates pair of keys (public/private)
  3. if the client needs to POST will encrypt payload using the API public key
  4. if the client request some data it will send its public key so that server can send back data encrypted in the public key if found

Implementing something like OAuth version 1 to share a key on top of HTTPS is an option - or is there any better alternative?

Any thoughts or better ideas?

5
  • 3
    Why do you expect a second layer of encryption to work if TLS doesn't?
    – vidarlo
    Dec 29, 2022 at 11:02
  • TLS works but from my understanding the trust model is too open, and because of it, it can be easily bypassed (when apps don't verify, SSL pinning, misconfigurations, etc) I see this "second layer" as a safeguard between client/server that helps to exchange information "safer", but maybe I am wrong this is why I am searching for better approaches.
    – nbari
    Dec 30, 2022 at 8:04
  • 1
    Whom are you protecting against? Reverse engineering of the app? TLS cannot be easily bypassed; you need a trusted certificate for the correct domain if the client is worth its salt... If the client accepts any certificate, your problem is the client, not TLS.
    – vidarlo
    Dec 30, 2022 at 9:28
  • I, also, think you need to explain or understand your data flow better. If you want to encrypt payloads, then do that. But, as you found out, key exchange becomes an issue. So, are you asking how to exchange keys securely when you can't trust TLS? And I also think that your understanding of the problems with TLS are not correct. In additon, if you have this advice from pentests, then they should have explained the goal better and the vulnerabilities they have seen.
    – schroeder
    Dec 30, 2022 at 11:38
  • 1
    Private key in the client is not safe but using the BE PK the client can send sensitive information to the BE in a secure manner. I understand other comments and agree but sometime it's needed another layer of encryption to overcome misconfiguration of TLS that can infer MITM. I guess this is the scenario.
    – robob
    Dec 31, 2022 at 11:49

1 Answer 1

1

The problem with all of these ideas - beyond the obvious issue that cryptography is hard to do right and your odds of adding meaningful security against an attacker sophisticated enough to pierce TLS are poor - is the same one that you're worried about with TLS: key distribution. How are you going to prevent the TLS-bypassing attacker from tampering with your key exchange? TLS (in most situations) solves this with PKI (Public Key Infrastructure) - certificates signed by certificate authorities and validated through chains of trust - but you're positing an attacker who can breach that (after all, certificate/public key pinning is nothing but an attempt to strengthen key distribution beyond PKI), at least for your own site. So, obviously, you can't rely on your own TLS for your alternative scheme; an attacker could just tamper with the request for the public key, and spoof the response with their own public key.

If you can distribute the key out of band - for example, through a app downloaded from an app store, rather than from your website - then maybe you're OK (if the attacker compromises the key for your app's backend but not for the app store). That's part of the premise behind pinning, at least. Alternatively, if you can distribute the key ahead of time - for example, on first use of the app, when hopefully the connection isn't being MitMed yet - that also can help (and is the other part of the premise behind pinning). Neither approach is perfect, but both raise the bar somewhat.

At the end of the day, though, I suspect your threat model doesn't make a lot of sense. Encrypting payment card data with a key supplied by your own server at the time the card is used adds basically no security. Furthermore, it's an almost entirely pointless thing to worry about; credit cards have protections against fraudulent use, and neither your users nor the payment processors are going to fault you for "letting" the card data be stolen because you merely implemented the standard TLS protections that secure every other transaction online. In fact, you're far, far more likely to introduce a vulnerability by messing with the encryption (though merely adding a second layer shouldn't be a problem, even if it adds effectively nothing). If your site is a big enough deal that you actually need to worry about this, you should be hiring security experts to help you design the system, and probably paying for hosting and so on that lets you use pinning.


With that said, if your goal is to hide information such as card data from yourself, rather than from a hypothetical highly sophisticated attacker, then something like what you describe makes sense. The process of converting card data into an encrypted blob that is stored in an external service where you (the app owner) can't access it directly is called "tokenization" and is common in some commerce apps. What you must understand, though, is that this doesn't actually prevent you (the app owner) from decrypting the card data if you want to; you'd just modify the tokenizer code to allow this. What it prevents is a malicious insider without total privileges (the tokenizer should be modifiable by extremely few users), or an external attacker who has compromised your main production environment (the tokenizer should be a totally separate service and be extremely hardened with minimal attack surface), from extracting the card data. Very distinct threat model. This probably won't help against an external attacker who can compromise a TLS connection of their choice though; instead of going for the one between your app and your main server, they'll go for the one between your app and your tokenizer (and replace the tokenizer's public key with their own).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .