1

I'll try to be as brief as straight to the point as possible, i'm new to this so please bare with me! I might be committing a massive mistake and not even realised! Please HELP! [facepalm emoji]

Application Requirements:

  • The frontend must be a website
  • User must provide his own API TOKEN and SECRET to a 3rd part API
  • While logged in on the website the user can manually trigger actions on such 3rd API through my application UI
  • While the user is logged out my service must do scheduled calls to the 3rd part service ( read as: one server must be able to read and send his keys via POST to a 3rd part service in plaintext )

Here are the steps i'm taking in order to decrease my surface attack:

  • Deploy a micro-service that will be responsible only for storing keys and doing background jobs

  • Generate an RSA key for my micro-service

  • Hide the micro-service from the user by only having the url on the backend side ( use my http server as proxy )

When the user manually execute an action through my UI:

  • I'll generate an RSA Key on the client side using his password ( must be strong ) as passphrase and generate a 1024 bit Key, send the public key to the HTTP Server which will send it to the SECRETS SERVER

  • On the secret server if the user was never registered i'll save this user_id and associated public key

  • When the user input his keys, i'll encrypt the keys with the PUB KEY of my SECRETS SERVER and sign with user's private key

  • Post it to my HTTP SERVER which will post to my SECRETS SERVER

  • My secret server checks if the message was signed by the pub_key he excepts and if it is, save the user data encrypted with it's own ( server ) private keys on the database

When a background job must be executed:

  • The SECRETS SERVER read the key from the database, decrypt the API KEYS, does the HTTP POST and remove the plaintext from memory

What could go wrong? ( as far as i understand! )

  • Someone gets access to my HTTP server, discovers my SECRET SERVER, crack into it, read the database credentials and the private key, get the API KEYS and run away.

  • Someone get access to my credentials, finds the secret server computer, manages to download the database, find the private key, get the API KEYS and run away.

Key questions:

  • What else could go wrong?

  • Generating an RSA key on the client side using user's password as passphrase is "good enough" ?

  • Will the RSA key generated on the client be constantly identical regardless of the computer they log in?

  • Does this even make sense?

  • On this thread if i understood correctly it's recommended to "stretch" the passphrase before generating the key, but since a user could reverse engineer the .js file on my website they would also discover how the key are stretched, right?

Thank you for reading it all through! I really appreciate any advice.

  • 1024 bits is below the minimum recommended size for an RSA key. Even 2048 is criticized if you want the keys to hold up for a long time; 3072 or 4096 bits is recommended. ... Also you should be using some kind of library for the encryption, not doing raw RSA yourself. – Macil Jun 23 '17 at 1:49
  • @AgentME would you please elaborate why i should use "some kind of library for encryption" ? I'm currently experimenting with this library: github.com/wwwtyro/cryptico and it seems to behave as i expect. – kroe Jun 23 '17 at 2:02
  • 2
    The overall design does look overly complex. If you're looking to provide a UI for a 3rd party functionality (e.g., Buffer) through API, you're looking for simple expirable bearer tokens - a la OAUTH. API Keys and secrets are hard to expire and manage. [edited for clarity] Your questions span your entire design; a high-level design review of a complex system is probably a lot to expect here, IMHO. You might get better answers if your focus is narrower. – Sas3 Jun 23 '17 at 2:54
  • Yeah the post is long and not many people are willing / able to read it all ( also i'm not the best writer! ), but IMHO it's a nice puzzle to solve, at least for me a cryptography noob! Thanks for your comment. – kroe Jun 23 '17 at 3:44
  • What kind of data do the 3rd party APIs have access to? Is this a financial application? Healthcare application? Or something else? Also, as @Sas3 alluded to, do those 3rd party APIs allow for Oauth authentication? – user52472 Jun 23 '17 at 15:44
1

This seems like an overly complex solution to the problem. An important thing to remember with cryptography is that even if the cryptosystem is implemented perfectly, if either of the endpoints is compromised, attacker can access the plaintext data. Your microservice does not need to be made secret, nor does it really need to be made separate from your main web application. Having it on a separate server really only adds complexity.

The best solution, if the 3rd party APIs allow for it, is to store and use OAuth tokens. Only store the API tokens/secret if OAuth is not available.

Regarding transmitting the data to the server, you do not need to implement your own encryption in the browser. Properly implemented SSL will solve the problem of transmitting the key securely. Consider using Http Public Key Pinning (HPKP). Be aware of the potential pitfalls of HPKP before you implement it.

Regarding the storage of the tokens, the OAuth/API tokens should be stored in a salted & encrypted column in the database using a symmetric block cipher, the key should be stored in some place outside of the database (to prevent it getting exposed via a SQL injection attack), and the web application/batch job should be able to access that key and decrypt the tokens. The key you use to encrypt the data will be shared across all of the records, and should not be made available outside of the server that your records are stored on.

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.