Note that there are some explanatory texts on larger screens.

plurals
  1. POAuthenticating requests from mobile (iPhone) app to ASP.Net Web API (Feedback requested on my design)
    primarykey
    data
    text
    <p>I'm designing a web site that will have a mobile companion (initally iPhone only). The web site will be an ASP.Net MVC 3 application. I'll also have an ASP.Net Web API site (MVC 4) to expose services to the iPhone application. The iPhone app will have its own form to capture username and password from the user and send that to the web API in JSON headers.</p> <p>I want to consider security from the start rather than an after thought. <em>I'm not a security expert by any means.</em> I've done a good deal of research to see how other's are handling authentication of a mobile application client from a web service. I think I've come up with a decent solution that doesn't involve hooking into to third party oAuths.</p> <p>I would greatly appreciate any and all opinions, advice, criticism and general WTFs that any of you can offer. :)</p> <p>My biggest concerns are:</p> <ol> <li>Ensuring that calls made to the web API are authorized</li> <li>Minimizing the risk of replay attacks (hence timestamps in the calls below)</li> </ol> <p>The iPhone app will be developed as such:<br> <em>Two strings are hard-coded into the iPhone app (same values for every user):</em></p> <ol> <li><b>Application ID</b><br>This is a string that is used to identify the type of client that is accessing the web API (iPhone, Android, Windows phone, etc).</li><br> <li><b>Application's Hashing Salt</b><br>This is a string that is used to salt hashes for user-agnostic requests.</li> </ol> <p><em>Two strings are stored in the iPhone app's local database (values unique to each user):</em></p> <ol> <li><b>API User Access Token</b><br>This is a string (token) provided to the client by the web API upon successful authentication and allows the client to access the web API without sending the username and password in each request.<br></li> <li><b>User's Hashing Salt</b><br>This is a string that is used to salt hashes for requests made against established user accounts.</li> </ol> <p><br> <br> The iPhone will make calls to the web API in the following manner:<br><br> <b>API Method: Create Account</b><br> Client Sends:</p> <ul> <li>New Account Data (Username, Password, First Name, Last Name, etc..)</li> <li>Application ID</li> <li>UTC Timestamp</li> <li>Hash of UTC Timestamp + Application ID salted with Application's Hashing Salt</li> </ul> <p>API Returns:</p> <ul> <li>New User's Hashing Salt<br><br>The idea here is that, when creating an account, I can use the application's hardcoded salt since it's not a huge security risk if that salt ever got out (through decompilation or some other means).<br><br> But for methods that access and modify the user's data I'll use a salt that is owned only by that user so it can't be used by an attacker to impersonate others.</li> </ul> <p><br> <b>API Method: Get Account</b><br>(Used for getting user's hashing salt for accounts that were created on the web site but haven't yet been synced on the iPhone. This happens when a user tries to log in on the iPhone and iPhone detects that it has no record for that username.)<br> <br> Client Sends:</p> <ul> <li>Username</li> <li>Password (hashed with Application's Hashing Salt)</li> <li>Application ID</li> <li>UTC Timestamp</li> <li>Hash of UTC Timestamp + Application ID salted with Application's Hashing Salt</li> </ul> <p>API Returns:</p> <ul> <li>Existing User's Hashing Salt</li> </ul> <p><br> <b>API Method: Log In (Authenticate)</b><br> Client Sends:</p> <ul> <li>Username</li> <li>Password (hashed with User's Hashing Salt)</li> <li>Application ID</li> <li>UTC Timestamp</li> <li>Hash of UTC Timestamp + Application ID salted with User's Hashing Salt</li> </ul> <p>API Returns:</p> <ul> <li>API User Access Token</li> </ul> <p><br> <b>API Method: Any Command (i.e. Create Post, Update Profile, Get Messages, etc...)</b><br> Client Sends:</p> <ul> <li>Command Data</li> <li>API User Access Token</li> <li>Application ID</li> <li>UTC Timestamp</li> <li>Hash of UTC Timestamp + Application ID + API User Access Token salted with User's Hashing Salt</li> </ul>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. COYour question is helpful to me Joe, as I'm trying to do something similar. I have a question though - when a user creates an account, you're sending the username and password without hashing them. Seems OK since it's just once. But if the phone tries to login to an account that's already created, you hash their username and password with the app salt. Is this really THAT much better than sending it unhashed again? I mean, I know it's a bit better, but sending unhashed info twice isn't much more unsecure than sending it once. Or am I missing something?
      singulars
    2. CO@AndrewBSchultz, you're right, and I wound up not encrypting on that first call. Since it's SSL and since that initial call happens only one time, there's a negligible risk of exposure.
      singulars
    3. COSending "unhashed" info any number of times is insecure. But the real point is that the entire API is protected with SSL, so all of the transfers are encrypted. Passing the user's salt from the server to the client is questionable. What's the point of that, really? Among other things, it means that you're computing password hashes in multiple places, which makes it very difficult to upgrade your password hashing algorithm when you discover that your existing one is broken (and eventually you will). Just pass the username and password, protected with SSL, and let the server do the hashing.
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload