I'm working on a product with strong security. Essentially there is an App, downloaded from the iTunes App Store. When the App starts up, it generates a strong RSA keypair and stores it in the Keychain. This key pair is the foundation for a lot of things in the overall system. The next step is for the App to use this keypair to generate a CSR (Certificate Signing Request) and present it to a CA (Certificate Authority) and request an SSL Client Certificate for the App key pair. The CA then records the UUID of the App. This process needs to be secured so that only the validated App can submit the CSR.

My question is how do I authenticate my App to the CA, to prevent something else to request these Client Certificates? I understand that we cannot rely on the certificate alone for security. Its only purpose is to prevent a layer of security between the App and the backend system and a "anchor" for User Security (outside the scope of this question).

Logic dictates that we should "give" the App something that only the App knows (i.e. a secret, encrypted and obfuscated in code). But this can be extracted with enough time and effort, thereby unlocking access to the CA.

Essentially I want to know how I can authenticate a piece of code.

Currently, our thinking is to generate a unique key pair at build time, embed the public key in the code (obfuscated) and use the public key to encrypt the CSR. The private key is in the backend. This ensures that only entities with the public key can submit the CRs.

Note - this process has no user intervention. It is not about the user, only about securely generating an identity unique for an instance of an App and issuing a certificate

My question is how do I authenticate my App to the CA, to prevent something else to request these Client Certificates?

There is generally no way to authenticate the client code. Any secret you embed in the app could be extracted. You must assume an attacker can send requests that an authentic client would.

Instead, what you can do is authenticate the user. You can give each legitimate user a secret license key and only allow a single client certificate to be signed per valid license key. (Probably with the ability to reset for reinstall, etc.)

As an example, such a scheme could look like:

  1. User buys app, downloads client and receives a license key.
  2. App asks user for license key. Sends a certificate-signing request to server that proves the license key.
  3. Server verifies the license key is valid and unused, signs certificate, stores the fact that it is now used.

The certificate signing request could be e.g. licence_key||certificate encrypted with the server's public key (which is embedded in the app). As long as an attacker cannot generate valid license keys on their own, they cannot get extra certificates signed.

  • 1
    What about: attacker tricks user into installing a rogue App, which performs as the genuine App (steps 2 and 3), then nefariously uses the key it generated and certificate it got at step 3? Users acting honestly are poor at detecting rogue apps, and sometime a paying user is an adversary (e.g. wants to split cost of registration with relatives). Unfortunately, aside from concealing a secret and how to use it into the genuine app and using code obfuscation to make it hard to reuse that into a rogue app (which is possible to a degree, but currently more art than science), I see no solution. – fgrieu Sep 21 '15 at 13:23
  • @fgrieu, true, that is still possible, but if the app is installed from a trusted source like in the question (assuming you trust the App Store), that should only happen with the adversary's key. And like you say, there you have to accept it can happen and plan what the certificate allows accordingly. – otus Sep 21 '15 at 14:18
  • From a publisher's perspective, the App Store does not prevent at all another developer from making an App that performs what I said, at least if the user is willing to download that App. Even is the user is not an accomplice, the App Store does not fully protect users from being tricked into installing an App when they want to install another. And, although that has little to do with the question: actuality tells us not to trust blindly what's on the App Store, even from reputable publishers. – fgrieu Sep 21 '15 at 16:22
  • @fgrieu, honestly, I know very little about how App Store works in practice. However, I would think there would be some way to tie giving the license code to purchasing the correct app (assuming that isn't already attacker controlled – otherwise there is no defense). Of course, an attacker could resell legitimate codes with their app, but whether that amounts to some kind of an attack depends on what the actual app is supposed to do with the certificate. – otus Sep 21 '15 at 19:13

You'll want to integrate something in the request that is unique for the device or the user. This can be an iOS specific identifier or a hardware specific identifier.

Furthermore, what you want is to make sure that the request came from your software. You can do this by authenticating the request somehow. For this you need a secret key. I guess the most logical thing is to have a single master key in the device and use that + the ID of the device to calculate a device key. Then you can use the device key to generate a MAC over the certificate. You can then send ID + request + MAC authentication tag to the server.

As you already found out, it won't be possible to completely secure this if you haven't got a pre-established trust relation with the CA.

  • I do not see how the answer's "integrate something in the request that is unique for the device" increases the confidence we can have that the genuine app made the request (which seems to be the goal: "Essentially I want to know how I can authenticate a piece of code"). I see how "something in the request that is unique to the user" could help, if the user could recognize a genuine app from a non-genuine one when giving that unique info, but users have poor judgment. Thus at the end of the day, the most effective way that I see to reach the question's goal is code obfuscation. – fgrieu Sep 21 '15 at 12:41

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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