3

I have an app that uses an API server and I do not want to have anything other than it to be able to use that API. I know this isn't totally possible, but I want to do what I can.

I don't think my current method of achieving this is the greatest and I'd like to scrap it and start over fresh. Here's how it works:

  1. The app picks a string from a set that I'll call the "entropy".
  2. Using that string it makes a hash of the current UTC date using the entropy as the salt
  3. It sends that hash to the API server which then creates the hash using every possible entropy from the set until it finds a match
  4. If it finds a match, a API key is generated for the app and sent back.

The server stores the entropy string, the API key, as well as the IDFV in a database.

When the app makes a request, it sends their API key, the IDFV, and a bearer token. The bearer token is a hash of the URL with the entropy string as the salt.

When the server recieves a request it:

  1. Selects the entropy string from the database using the API Key and the IDFV as search parameters.
  2. Generate it's own bearer using the URL it's responding to, and the entryopy from the above select.
  3. Verify that the entropy strings match

If the select query returns nothing, or if the bearers don't match the server will return a 403 and not proceed.

The problems I'm worried about are:

  • If the user has an incorrect date on their device the registration will fail. Likewise,
  • If the server has an incorrect date the registration will fail
  • If the app starts registration at 23:59:59 and there's a 1s delay time to the server (which over 3G is totally plausible), the registration will fail
  • With a hard-coded list of entropy strings can the app be decompiled and the strings extracted
  • With only a limited number of entropy strings it's possible to find all of them with enough time.

Some of the things I have took into consideration:

  • All requests and responses are served over HTTPS
  • The API server rate-limits requests to hamper brute force attempts
  • The API server is behind CloudFlare to also do some basic attack prevention.

What I want to know is what would be a better way of going about this that doesn't require any extra user interaction? The iOS app is built using Objective-C and the API server is built using Ruby.

  • What kind of attackers are you trying to protect against? – whatsisname Apr 6 '18 at 1:54
  • 3
    @whatsisname this question is from 2015 so it's from a time when I didn't have any clue what I was doing. I've come to realize that there's next to nothing I can do to really achieve what I wanted as if somebody would reverse engineer the app, they could always get access to the API. – ecnepsnai Apr 6 '18 at 2:13
1

OAuth pairing may be a good alternative. For example:

During the initial login, the device is uniquely identified and paired with the mobile user's account using the OAuth 2.0 protocol (http://tools.ietf.org/html/rfc6749). All requests to the Salesforce service are made using the OAuth token established through the pairing created during activation. After initial login, there is no exchange of a password in the communication between the mobile client and the Salesforce server. For this reason, the Salesforce password is not stored on the device and is not required even when the password is changed or has expired.

Which uses the following process:

Use a refresh token for apps that don't have access to the private key, such as mobile apps. A third-party system can generate the refresh token using the private key and provide it to the mobile app. The app then uses the refresh token to generate an access token

In regards to identifiers, do not use IMEI or UDID as they are shared with other apps. As an alternative:

We recommend that developers avoid using any device-provided identifier to identify the device, especially if it's integral to an implementation of device authentication. Instead, we recommend the creation of an app-unique "device factor" at the time of registration, installation, or first execution. This app-unique device factor in combination with user authentication can then be required to create a session. The device factor could also be used as an additional factor in an encryption routine.

References

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.