How safe are client SSL certificates in a mobile a

2019-01-21 03:56发布

问题:

I'd like to have secure communication between my Android/iOS app and my Internet-accessible backend service, so I'm investigating HTTPS/SSL.

If I create self-signed certificates, then put a client certificate in the app and cause the backend service to require that client certificate, is this truly secure?

Here's why I'm asking. It seems that the client certificate could be "hacked" by interrogating the .apk. The client certificate is just a string constant, right? That means anyone could use the client certificate to access my backend. Is the .apk (and iOS equivalent) sufficiently opaque to prevent the client certificate from being discovered?

回答1:

The certificate is harmless. It is the private key that needs protection, and it is only as safe as the device itself, no safer. Distributing the certificate and private key with the application just means that anyone who has the application has the key, so it doesn't provide you any security whatsoever. I think you need some kind of post-install registration step.



回答2:

Are you doing client side authentication with certificates over SSL? Not that it really matters for this question. Any private keys you store in your app is accessible to an attacker. Each client should have it's own certificate and key pair, to prevent a mass compromise. Your server should also enforce protections, ensuring a compromised client can't just request anything.

This is true for any authentication scheme. If you embed passwords, API keys, decryption keys, whatever. Anything on the device should be assumed to be accessible.

The added security from certificates in part comes from there being nothing to brute force. If you went the username/password route for each clients, passwords can be guessed. Same with API keys (albeit they are longer and harder). With certificates, it's an entirely different class of attacks, and a considerably harder problem.

But, most importantly, the backend service shouldn't allow the app to do anything it wouldn't normally do.

Now, dealing with certificates, you're going to have a whole host of other problems. You probably want to sign each client certificate with your self-signed CA cert. Managing that CA cert can be problematic, depending on your use case. Are you going to generate these client certs on the fly, or manually yourself? Meaning, is this an app that a million people can download, and you need an automated system for generating them? Or is this a private/internal app that you personally will handle generating certs?



回答3:

Typically, client SSL certificates are stored in keystores (BKS formatted in the case of Android) and the keystore is included as a resource within your APK. Keystores are encrypted and protected with a password. So, that client certificate cannot be readily extracted from an APK, as it is stored in an encrypted form.

Now...what do you do about the password? Here is the crux of the matter and you have two alternatives.

If you want your application to be able to communicate with the server (so, to be able to access the certificate) without user interaction, you will need to embed the password into your application and then, yes, an attacker could reverse engineer your code to find it, grab the keystore, and then decrypt it to recover the certificate. You can apply techniques like obfuscating your code so that it is harder for an attacker to do so, but this will just slow someone down and not prevent it.

Your alternative is to prompt the user for a password every time your application communicates to the server and use that to decrypt the keystore (or ask when the app starts and cache the certificate for a certain amount of time). The advantage here is that if someone reverse engineers your APK, they will find the encrypted keystore and no password so your certificate is safe. The disadvantage is having the user provide the password.

Which approach is best? It completely depends on the sensitivity of the data you are concerned with and the level of risk you are willing to accept. Only you can answer that question.



回答4:

Daniel Guillamot, some tricks I've come over:

  • split server side key. Make the passphrase for the SSL-key be the result of string-in-app XOR string-fetched-from webservice.
  • make the string-in-app be created by calling some app-functions, instead of hard coded string.
  • deny tracing the app while it's running, to avoid someone picking up the final passphrase when it's calling the decryption of the private key. Ref: http://books.google.no/books?id=2D50GNA1ULsC&lpg=PA294&ots=YPQQ7DLjBD&dq=The%20example%20just%20shown%20demonstrates%20how%20calls%20to%20ptrace%20can%20be%20hijacked&hl=no&pg=PA293#v=onepage&q&f=false

I'd love to hear more if anybody have other ideas.



回答5:

APK can be accessed and copied, so putting anything in it won't help. Activation and maybe binding the certificate to the device after installation would be necessary. Binding can be done for example by putting the IMEI of the device to one of certificate extensions and passing the IMEI together with the certificate by your application (or, better, pass IMEI after authentication and establishing the secure channel).