9

I am building a web service that has to be only accessible for iOS apps. In the future I want to expand to a mobile web-site to make my service also available for other mobile operating systems.

Now, I have everything working through an API. my users can register, search companies, order products from those companies, and track their orders. It's not active yet, but it's working..

I am facing one major problem: how to secure this?

For the last few days I have stopped coding, and I have constantly been busy with searching the web, StackOverflow, and Information Security for how to do this. I have found that the way Amazon secures their API would be the best solution for me. The way Amazon secures its service is explained here. I have tweaked it a little bit for my service:

  1. User registers and gets private API key + public (identification) key
  2. User enters credentials and taps "log in". App creates hash out of the variables + private key. App sends variables + time stamp + hash + public key to API
  3. API looks up public key in database, finds private key belonging to that public key (if public key is valid). The API then creates hash the same way as the app did. If the hashes are the same, the request (log in in this case) is executed.

This way of securing a service makes sense to me, and I can code most of it. but I have a major problem and I can not find any solution to it:

  • The user gets a public & private API key when an account is created. The public key can be sent from the server to the user device, because that is not necessarily a secret. Since the private API key can never be sent over the wire, how on earth can I make sure that an account logged in on a user's device knows the private API key that is created on the server?

Does anybody know how to solve this problem?? any help would be highly appreciated!!

2
  • Not sure if this is what you're looking for...but maybe you might want to use HTTPS to prevent eavesdroppers from intercepting your key. Certificate Pinning is the best way to do this and here is an example program that does it. owasp.org/images/9/9a/Pubkey-pin-ios.zip . Also...Your architecture sounds extremely confusing to me...There are far simpler authentication scheme to use
    – user11869
    Dec 9, 2013 at 14:28
  • Seems pretty clear- I have the same question. Have you found a solution @Joris416 ?
    – james
    Mar 28, 2016 at 19:35

2 Answers 2

1

Why do you want the clients to have their own private keys? I'm trying to understand how your scenario is supposed to work but am a bit confused about what you're trying to achieve.

In general here are a couple of comments that may help:

  1. HTTPS is how you can establish a secure communication channel with clients. Once you do this you can transfer whatever you want securely over the wire client <-> server. This is the same thing your bank does.

  2. Article you link to doesn't say anything about HTTPS, looks like they're intending to send that over just HTTP. You should use HTTPS not HTTP for anything you wouldn't want compromised (such as a logged in user). Why try to build your own encryption mechanism when you can use HTTPS? Using HTTP for any kind of authentication sounds like terrible advice to me.

  3. I'm not sure that your clients really need their own public/private key pair. Typically it's a server that's securing your application communication and that has a certificate with private key. Clients will still have a user name and password right? That's the authentication for your client (not a certificate) and you can send the user/pass to the server once you have a secure HTTPS channel established. Server side your app will verify the client login credentials are valid and give the client a way to say "I'm already authenticated for 30 minutes" via a cookie or session mechanism. Obviously once a client is logged in, communication needs to continue to happen over HTTPS or your authentication token/session could get stolen.

Bottom line, if you're just trying to secure communication between clients and a server then use HTTPS and don't re-invent the wheel.

0
+50

Yes, there is a solution. Create the public and private keys on the client side. Then only the client's public key needs to be transmitted, from the client to the server. The server has its own public and private key pair, of which it shares only the public key.

The scheme you describe should not require that both parties have copies of the public and private key. You described a symmetric communication scheme, where the data transmitted to and from the server is encrypted with the same public-private key pair, and both parties require the public and private keys.

The solution is to introduce some asymmetry. The client should have the server's public key. The server should have the client's public key. They should each have their own private key. If you wish the server can use the same keys for all the clients, or you can generate new server keys for each client. In any event, there is no need to share the private keys.

Good luck with your implementation. Do post a comment to let us know if it works!

3
  • there seems to be a need to share the private key with client/server since the HMAC generated uses the private key. if the client and server have different private keys, the resulting HMAC(generated by both sides) will be different, and thus rejected
    – james
    Mar 29, 2016 at 14:34
  • According to RFC 2104, HMAC requires a secret shared key. tools.ietf.org/html/rfc2104 Mar 29, 2016 at 14:59
  • If you do not want to transmit the secret key, then create it twice by using exactly the same algorithm on both computers. You can set this up by sharing some kind of one-time-pad, instead of sharing the secret key. One-time-pad: en.wikipedia.org/wiki/One-time_pad Mar 29, 2016 at 14:59

You must log in to answer this question.

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