I have an endpoint in which the server has to be sure of the authenticity of the client making the API calls. I therefore imagined the best way to do it is to include something like a digital certificate or a secret in the client which would have to be encrypted and distributed within the binary that goes to the AppStore. How could I add such a certificate in order for it to be safe? What alternatives would I have if not possible?
Apple helpfully provides a set of APIs that would allow you to store a certificate securely, and that would probably be what you should use. Past that, there is no way to guarantee that your certificate is not stolen by a sophisticated attacker; any key you distribute can be stolen, unless you are transmitting it over a secure channel to a trusted recipient.
Related
I have a client server scenario.
I have both thick client and a thin client (browser) which communicates with my server.
My thick client uses X-509 system certificate for client certificate authentication scenario and communicates with the server
Also this certificate is used for used to generate signed URL (with expiration time) for my thin client to communicate with my server which is used for integrity and authorization purpose. I also have a token based approach for authentication purpose in this case.
Now i want to complete move my authentication mechanism to OAuth based flow using client credentials or auth code based.
I understand that authentication and authorization can be moved to OAuth based communication. But how do i move my signing (digital signature) based use case to OAuth from certificate based ?
I don't think there is any other way than to use certificate based PKI mechanism for digital signing. Can the private and public keys be distributed other than the certificates ?
Best Regards,
Saurav
Can the private and public keys be distributed other than the certificates ?
You may generate key pair using openssl (command line - openssl.exe) or any cryptographic library or CSP of crypto device. Instead of distributing it, you may have a piece of software which user may use at his end to generate public key and private key and share public key if required and store private key securely. But question remains how user would store private key securely and there comes certificate storage formats like PFX which is password protected (encrypted using password you provide) or storing private key in smartcard or usb token which are cryptographic devices. You may program these devices to generate our own keys and not necessarily store certificate issued by CA.
For browser based access to user's private key, you may need to use browser extension.
Refer to this SO answer for accessing user's keys from browser for authentication.
I need to prevent MIM(Man in the middle attack) for my native apps which use Azure API management. Though we have secured API management using JWT, we need to secure the HTTPS requests coming from apps to prevent a man in the middle attack. What is the best way to achieve SSL pinning using Azure API management?
I tried adding a self signed SSL certificate in API management certificate, but the apps are not able to use that certificate. What would be the best way to solve?
Using a certificate signed by a public CA is really your only option for a publicly accessible endpoint. You could use a private CA if you're in an enterprise environment with the CA trusted on all devices connecting to the endpoint.
Currently, I am getting an API key from the server after logging in and using it to make http requests. I currently store the API key in the iPhone app's database. However, I've heard that I should store it in a keychain from a colleague. So, I searched on Stackoverflow and seen questions regarding this. It seems this isn't really a secure way of storing API keys at all.
Secure keys in iOS App scenario, is it safe?
In iOS, how can I store a secret "key" that will allow me to communicate with my server?
I don't know a way to stop hackers from reverse engineering to get the API key from the iOS app. A user on StackOverflow basically said it will only overcomplicate things for little to no benefits.
I need to find the post, but someone recommended to just make sure you're making a secure API request (SSL certificate) and you have a way to remove the API key if someone is hacked.
As already pointed out by #jake you should use a token tied up only to the user instead of an Api Key for all users, but other enhancements can be done for further protect your App when doing the http requests.
The user token can be a signed JWT token and then you can enhance the security of the communication between your server and the App with Certificate Pinning in order to protect against Man in the Middle Attacks.
Other techniques like the use of OAUTH2 and hiding secrets can be used to enhance the security of your App and you can read more about it here.
Keep in mind that Certificate Pinning can be bypassed by hooking frameworks such as Xposed that contain modules specific to bypass the pinning, but still another layer of security that you should not discard once it will increase the effort necessary to hack your App on the device and will protect your App against Man in the Middle Attacks.
For ultimately security between your App and the back-end you should use an App integrity attestation service, that will guarantee at run-time that your App was not tampered or is not running in a rooted device by using an SDK integrated in you App and a service running in the cloud.
On successful attestation of the App integrity a JWT token is issued and signed with a secret that only the back-end of your App and the attestation service in the cloud are aware and on failure the JWT is signed with a fake secret that the App back-end does not know, allowing this way for the App back-end to only serve requests when it can verify the signature in the JWT token and refuse them when it fails the verification.
Once the secret used by the cloud attestation service is not known by the App it is not possible to reverse engineer it at run-time even when the App is tampered, running in a rooted device or communicating over a connection that is being the target of a Man in the Middle Attack.
You can find such a service in Approov that have SDKs for several platforms, including IOS. The integration will also need a small check in the App back-end code to verify the JWT token in order the back-end can protect itself against fraudulent use.
JWT Token
Token Based Authentication
JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.
Certificate Pinning
Pinning is the process of associating a host with their expected X509 certificate or public key. Once a certificate or public key is known or seen for a host, the certificate or public key is associated or 'pinned' to the host. If more than one certificate or public key is acceptable, then the program holds a pinset (taking from Jon Larimer and Kenny Root Google I/O talk). In this case, the advertised identity must match one of the elements in the pinset.
OAUTH2
The OAuth 2.0 authorization framework enables a third-party
application to obtain limited access to an HTTP service, either on
behalf of a resource owner by orchestrating an approval interaction
between the resource owner and the HTTP service, or by allowing the
third-party application to obtain access on its own behalf. This
specification replaces and obsoletes the OAuth 1.0 protocol described
in RFC 5849.
Disclaimer: I work at Approov.
A more secure mechanism would be to return an authentication token on login. This authentication token should be unique to the user. If you have proper authorization and security mechanisms on the backend (to mitigate DDOS attacks, injection attacks, users accessing other user’s data, etc) then who cares if they get their authorization token from the keychain or wherever it is stored? Since the authentication token is tied to their account you could just invalidate the token so it stops working if the user is malicious. And you could even disable their account altogether if you have the right mechanisms in place on the backend.
Many of the security mechanisms can be automated on the backend. Platforms like AWS can easily be configured to automatically disable accounts that are doing certain malicious calls to your backend.
How can I decrypt PKPaymentToken (Apple Pay Payment Token), in iOS (using Objective-C or Swift)?
It's recommended to decrypt the payment token at the server end (ideally done by the payment processor), but what if I want to decrypt the payment token data on the client side (iOS end).
Don't do this. It is a terrible idea. To decrypt the payment token requires your private key. You would have to embed this key into your app, which would allow anyone to take it and decrypt your payments. You should never decrypt the payment data on device for this reason.
Instead, store the private key securely on your servers and decrypt there, or see if your payment processor offers direct support for Apple Pay token decryption.
The process used to decrypt an Apple Pay payload is confidential and Apple only releases it to select payment gateway / processor partners. The private key you have for your merchant certificate to enable Apple Pay is used as part of this process but it is not the sole component and there is a complex series of steps to actually receive a card number (3-D Secure) usable for processing.
I would recommend signing up for a developer account at a place like Stripe and using their sandbox environment to test processing of encrypted Apple Pay payloads. Stripe's merchant tools will then expose redacted card info and other authorization details you may find helpful.
How to verify if the API being hit is from the actual application and is not going through any MITM attacks.
I understand SSL certificates can be used to achieve transport level security and the app can be sure it is taking to the correct server, but how can I attain the same thing from app side.
I just want to make sure that only my app is hitting my services and the hit is not coming from somewhere I don't trust.
Thanks
Have a look at SSL again - it offers client certificates, for example, to do so. Yet, this only shifts the problem as an attacker might use the same mechanism the apps use to get certificates. (An shared API token is often considered okay as well and much easier to implement.)
In general, you cannot achieve a guarantee for that. You might get a good result by issueing certificates based on user authentication by external means (e.g. make users put in their user names and passwords) or make it hard for adversaries to abuse your API by using reverse turing tests (e.g. completely automated programms to tell computers and humans apart, aka CAPTCHAs).
The same way that the client validates the server based on its server certificate, SSL supports the server issuing client certificates and requiring communication to be signed with that specific certificate.
With this approach it comes down to possession of the certificate rather than, say, knowledge of a password. Which in the case of mobile is problematic, because an attacker can more easily gain physical access to your device and read your app's documents. So take care to store your keys in your keychain.
Also, your method of handshaking with your server and asking it to issue a client certificate becomes a security bottleneck. An attacker could, since she has physical access to the device, sniff the traffic and easily figure out the API calls needed to get the server to issue the proper certificate.
Read Apple's business oriented document on security in iOS here.