3

The company I work for is building a mobile app that communicates with two APIs.

The first API is owned by us. Among other things, it manages OAuth2-style authorization and authentication.

The second API is not owned by us. It is a third party data source that only offers authorization via HTTPS Basic Auth headers. Every request to this API must include a username and password. The login credentials for the second API are different than the credentials for the first API.

We would like to store the users credentials for the second API so that the user need not re-enter their username and password every time they open our mobile app and make a request to the second API.

We've devised the following solution:

  1. User opens our mobile app and authenticates with the first API (I am skipping the details of authentication with the first API because it is not relevant to the primary issue).

  2. User enters their username and password for the second API.

  3. Mobile app generates a PGP private key, public key and randomized passphrase for the private key.

  4. The mobile app would then encrypt the username and password for the second API using the public key.

  5. The mobile app uploads the private key, encrypted username and encrypted password to the first API. The first API stores those values on a users table.

  6. The public key is discarded by the device. The passphrase for the private key is stored as securely as possible on the device (device keychain if available).

  7. Any requests that were previously sent from the mobile app to the second API are now routed through the first API. The request will include the passphrase (stored only on the mobile device) so that the first API can use the private key to decrypt the username and password and send off the HTTP Basic Auth request to the second API.

In order to obtain the username and password in plain text, a hacker would need to compromise both the user's device (to get the passphrase) and our first API (to get the private key and encrypted login). Even if both the mobile device and our first API were compromised, the hacker would only get one password because each user generates their own PGP private key / passphrase combination.

This seems secure to us, but I wanted to make a post here to see if someone could point out any flaws or suggest improvements. We're curious if there's a way we can help protect against scenarios where the users mobile device is compromised. As it stands now, if the users device were compromised, the hacker would not learn the users password but they could use the private key passphrase to send off illegitimate requests and read sensitive data from the second API.

2
  • 1
    Any specific reason you are using asymmetric encryption? It seems to me that you could solve this using AES. You would generate two keys, one for encrypting the password and the other one for encrypting the first key. You would send encrypted key to the API and store the key used for encrypting it in the device. Why are you delegating access to second API to your API? Why don't you do it on your device? Any specific reasons? Apr 5, 2017 at 9:26
  • Upvoted. I hadn't thought of using symmetric encryption like that. Regarding your second question, I neglected to include an important detail on the second API. Each of our clients has a "second API" and that API often sits behind a firewall. Our first API is given protected access to the second API (via a firewall exception or VPN link). Mobile devices cannot directly reach the second API, so we route their requests through the first API en route to the second API.
    – Elliot B.
    Apr 5, 2017 at 17:21

1 Answer 1

1

To my mind, the weak point here is that you are storing and decrypting user passwords to the second API on your platform. If the endpoints of the first API are compromised, an attacker would gain access to both to the encrypted usernames/passwords, and any passphrase submitted by a user.

You've swapped the potential compromise of a single username/password on a device for the potential mass compromise of usernames and passwords on your platform.

1
  • Upvoted. This makes a lot of sense. I think what we'll do is flip around the storage of the private key passphrase from the device to the first API and the private key and encrypted password from the first API to the device itself. Is that what you would suggest?
    – Elliot B.
    Apr 5, 2017 at 17:14

You must log in to answer this question.

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