Securing public APIs for access by intended people Only - express

I have several endpoints to be accessed by third party. (This are not registered users)
I am looking for the best way to ensure no anonymous requested receive the data.
I have thought of using RSA, i give a public key through another endpoint, that expires after like 10 Minutes to requester, they then use that public key to encrypt the Data like format like {requests:'users'},
but that would mean if an outsider gets to know this format {requests:'users'}, he/she is able to request for private key, encrypt that data with it and still be in position send a successful request.

Related

Is there a way to authenticate a user's wax/EOS wallet on the server side without making any blockchain transactions?

I'm trying to authenticate a user's wax wallet identity on the server. The method I'm trying to follow is this -
The client sends the server the (claimed) WAX wallet address
The server creates a random hash and sends it to the client
The client creates a transaction with the hash and signs it. Instead of pushing it to the chain, the transaction is created with broadcast set to false and it sends the signed transaction to the server
This is the part where I'm having a problem. What I want to do is use the eosjs API to get the actual public key of the wallet address, and then use eosjs-ecc's recover or verify methods to get a public key from the transaction and verify that it is the same. When I try this, it is producing different public keys each time and none of them match the actual one.
Here's the code I have at the moment: https://github.com/udbhav-s/waxlogindemo
If the method I'm trying isn't possible, is there any other way to authenticate a user without using on chain transactions?

what happens to JWT if someone gets my private and public key?

It seems to me that if my private and public key are compromised (which i use to sign and verify JWTs), that anyone can independently generate JWT tokens for themselves to use on my API?
Whereas on the other hand if I generated my own tokens myself, and stored a look-up table of 'one-way-hashed user id' => 'token', then if someone broke into my system, they would not be able to generate tokens to use on my API, and they would also not be able to use the tokens (because they would not know which token belonged to which user)
If someone breaks into your system and it is still secure, then you made a secure system; nothing to worry about.
with JWT, it appears to me that if someone breaks in, I do have something to worry about.
It seems to me that if my private and public key are compromised (which i use to sign and verify JWTs), that anyone can independently generate JWT tokens for themselves to use on my API?
Yes, that's correct.
Public keys are intended to be public and can be distributed.
On the other hand, private keys are supposed to be private and must be kept secure in your server. Anyone who has access to the private keys should be capable to issue tokens.
Disclosing your private key is a huge security breach.
It seems to me that if my private and public key are compromised (which i use to sign and verify JWTs), that anyone can independently generate JWT tokens for themselves to use on my API?
As also pointed out that you need to keep your Private Key Secure , the best way to keep it secure is to use an HSM for signing your data , in this case you can extend the JWT generator to sign the data through a crypto dll inside the HSM , this insures that the private key is never exposed outside the HSM
Whereas on the other hand if I generated my own tokens myself, and
stored a look-up table of 'one-way-hashed user id' => 'token',
Any one can generate your non-keyed hash. Secure hashes involved a private key which becomes a digital signature. Now we've come full circle, because that's exactly what a JWT token is.
Alternatively, you store them in a datastore, but now you must query this on every round trip. Most ticket(cookie)/token authentication systems use public key verification, which verifies the validity of the ticket/token without a database roundtrip.
If you store them in a datastore, now you must track expiration in the datastore as well. Tickets/tokens can have an expiration built into them. The nice thing about tickets/tokens is the client holds them. You can expire a session more quickly than the authentication. I.e. often you get a ticket that may allow you to be logged in for 2 hours, but the web server can expire your session in 10 minutes to reduce memory usage. When you access the web server in 15 minutes, it will see your ticket/token and see that it is still valid, and create a new session. This means at any point in time the server is tracking far fewer idle users.
JWT issuers are great for distributed systems, where authentication is shared. Rather than reimplement the authentication in every system, exposing multiple systems to the private key, as well as potential bugs in the authentication, we centralize it to one system. We can also leverage third party integrators that generate JWTs. All we need to do is get their public key for verifying the JWTs.
If someone breaks into your system and it is still secure, then you
made a secure system; nothing to worry about.
I have your list of nonces you were saving in your database now, and can login as anyone. I also likely have your connection strings, even if you're encrypting your application config, if I have root access then I can access the same key store that's used by the application to decrypt them. Now I get your username/passwords from your database and can login as anyone, regardless of what authentication scheme you use.
You'll be hard pressed to find a system that can still be secure after someone's gained root or physical access to the machine.
There's a small handful of systems that have purpose built hardware for storing keys and handle requests for encryption operations through an interface, thus ensuring the keys are protected at a hardware level and never accessed directly from software:
https://en.wikipedia.org/wiki/Hardware_security_module

Understanding Stripe's API authentication

Stripe's API uses HTTP Basic Authentication over HTTPS for authentication. Per the instructions, this requires including a secret API key in the request.
However, the Stripe dashboard provides us with two keys, one public and one secret. What is the public key used for?
pk_* keys are used in javascript client, since everyone can view this key by looking at html source code.
If someone obtains this public key there're only few operations that they can do e.g. collecting credit card info, request for tokens etc.
In contrast, your secret key are used for all crucial operations e.g. charge a credit card, create new customer etc.
Stripe.setPublishableKey('pk_*');
see https://stripe.com/docs/stripe.js

Correct way to manage user auth over REST api?

I have done a lot of research and I can't work out if this is the best way to achieve what I need.
I have a generic web app and I want to create a generic mobile app to go with it. In order for users to save data/access user specific data/etc they have to log in and the login has to be authenticated over my web app's REST api.
So the api has a private and a public key for the mobile app. The public key tells me where the request is coming from (the mobile app) and the private key is used as a "salt" to hash the query string which can then be rehashed on the web server when the request comes in and compared for validity.
To log in the user enters their username and password which is then sent as query string vars as per the method above. The query is checked for validity at the other end and the username+password pair is checked against the database. If the login is correct a random "auth token" is generated for that user and the public key and sent back to the mobile app for storage locally on the device.
When the next request comes in from the mobile app one of the query string variables is the "auth token" from earlier which is checked for validity (with the app's public key) against the "auth tokens" table in the database. If it is valid then do the request.
My question here is, have I got this right? Is this the best way to achieve what I need? The last step seems really insecure as both the public key and the auth token will be visible if the request is intercepted. Obviously the request will be checked against the hash of the query string and the private key at the other end and this will make sure the request isn't coming from anywhere malicious.
Are there any other steps, or things I've missed which would be useful? For instance I was reading that there should also be a timestamp variable which should be checked against a 5/10min time frame in the request. Any timestamps older than 5/10 mins and the request should be rejected. Is this important?
Thank you.
What you are describing is basically a homebrew version of 2-legged OAuth. There are many implementations out there that you can basically use. Whenever it comes to security related stuff, I go by: If others have already done it, don't reinvent the wheel. OAuath is used by many big sites out there (Twitter, Facebook, GitHub, Google, ...) and they have done a lot of research that went into the OAuth standards. So I'd suggest to use those.
If you are concerned that messages you send may be intercepted, you should use HTTPS... Which is a good idea in general, if you are passing around username and password combinations over the wire.

REST authentication / authorization

I need some advices on how to secure my application:
I have a REST service, using Spring MVC 3
I have my client application, using Ext GWT 2.2
Users credentials are available on the server side only.
SSL available
REST services should only be used by authentificated users.
I have read about HTTP Digest , token based authorization, oAuth etc, but I need some clarification and advices on how to secure my application, and which methods are the best in my case.
here is the methodology we created for our applications, works very well, and is very secure.
this is a very conceptual explanation, there is a lot of code that backs this up, FYI
When user authenticates or creates account, the server returns an x.509 certificate, base64 encoded, that is unique to for the user. The server stores a copy.
Everytime the client needs to access the REST API, client creates a JSON string comprised of the following.
The Users Unique ID (UserID)
A GUID or UUID, that guarantees this call is unique,(CallID) (protects against replay attacks)
A Dictionary (collection of Key/Value) of each parameter of the rest call
we then encrypt that string with the x.509 public key, and encode it back to base64 string, and take this encrypted value and add the UserID to a json object we call the token.
we then put the token into header of each call, and call it something like: X-Auth-UserToken
On every call the server takes the token, looks up the users certificate based on the userID, then verifies that the encrypted part of the token can be decrypted with the private key that the server holds for the user.
once decrypted, the server takes the CallID and verifies that it is unique, against its own calllog db.
if it checks out, the user is authenticated.
once the user is authenticated, you can apply your own authorization rules based on the users uniqueID.
of course, all the above is over SSL.
let me know if you need me to drill down on any parts.