REST authentication - Digital signature? - java

I am trying to secure my REST API developed using Spring MVC.
On google search I came across this link.
Is this the best approach ? Does it uses Digital Certificates ? Or Digital Certificates used only for SOAP based Web services?
Please also point me if there are better alternatives for REST authentication.

Is this the best approach?
What is "best" depends on your requiremements. The benefits of this approach are
Fairly easy to implement
No obvious vulnerabilities as long as the Secret Access Key stays secret.
Not so nice:
Both sides have to know the Secret Access Key, so you as a user must trust the provider of the REST service keeping your Secret Access Key secret. In most cases this is probably not a big limitation, but still ...
Does it uses Digital Certificates?
Nope. No certificates involved. With the exception of the SSL connection that is probably used to give the Secret Access Key to you.
Or Digital Certificates used only for SOAP based Web services?
Not true. You can use https (SSL) for REST, which typically involves the presentation of a certificate by the server to authenticate itself. You can also configure it so that the client has to authenticate itself with a certificate using SSL. This would be a nice solution, but is rather tricky to implement on the client side. It's not rocket science, but reading and understanding the handling of Certificates and private and public keys can be tricky. You'd also need some trusted Root CA, which is either a lot of work to setup or rather expensive to use if you use one of the established ones. I'd consider this approach when I'm working on internal services of a large company. They often already have this kind of infrastructure.
Please also point me if there are better alternatives for REST authentication.
As said above: This is a pretty good approach for most services. Using a PKI with client certificates would be an alternative, better in some settings.

You can simulate public/private key authentication like this
You need two basic things!
UserId / Application Id ( To check this application is allowed to access this application) (Private Key)
A random key for the API ( to check this method is allowed for the then authenticated application)
The Rest service (Server Side) will have a record of all the allowed application through "Application ID"
Now you can use these two keys in ur own algorithm . For example, you can create a simple HASH out of it.
The scenario would be, you are encrypting your API with a public key ( You API random key).
The client who is calling the method, is decrypting with his private key (Application ID)
When the client sends, his Application Id, you can , generate the HASH out of his Application Id and the API random key and make sure that, this application is allowed to call this method.
The Advantages here are:
1. The Server side can change the encryption algorithm, which client need not to be worried about
The server can change the method encryption (The public key), which the client need not worry about
The Client CANNOT change the private key(Application ID). If he changes, the server will reject it. In other way, a non-registered application cannot access the Rest Service

Related

How to securely store credentials for external service

I'm developing an budgeting application that uses a set of tokens and secret keys to access an external financial service, where a token-secret pair map to a single account. In this system, a user can have multiple accounts and therefore multiple sets of token-secret pairs. The token and secret can be used to access the transactions for an account, which means that the token-secret pairs should be securely stored (and be guarded against nefarious access or tampering). Although these pairs should be securely stored, the external financial service API requires the token and secret in plaintext.
What is a secure technique for storing these credentials at rest but providing the external service API with the original, plaintext credentials?
My application is a REST-based Spring Boot application written in Java 9+. Although there have been other answers I've seen on this topic, many of them are specific to Android and use Android security techniques (as are thus not applicable to my application). This application also uses Spring Data MonogDB to store other non-sensitive information, but if another technology is required for satisfying the above security requirements, I am open to suggestions.
This is not a problem that can be solved inside Java.
The token and secret can be used to access the transactions for an account, which means that the token-secret pairs should be securely stored (and be guarded against nefarious access or tampering).
The fundamental issue is who you are securing this against:
If you are trying to secure it against the people who manage the platform, it is pretty much unsolvable1.
If you are trying to secure it against "ordinary" (i.e. non-privileged) users, then you can either rely on ordinary file system security (plus standard service "hardening"), or you can use something like a Spring Vault or a Hardware Security Module if local file system security is insufficient2.
If you are trying to secure against a hacker who might be able to acquire the privilege of a full administrator, this is probably unsolvable too. (Though a hacker may need to be sophisticated ... )
Note that you can do things like saving the secrets in a Java keystore, but in order to do that the JVM needs the secret key to the keystore in order to get the secret. And where do you store that secret?
Aside:
... many of them are specific to Android and use Android security techniques (as are thus not applicable to my application).
Those techniques typically assume that the platform itself is secure, and / or that it hasn't been "rooted" by the user.
1 - So, if your goal is to embed some secrets in an app that you give to a client to use ... give up. If that problem was solvable, priracy of software, music, videos, etcetera would have a simple and reliable technological solution. Clearly ... it hasn't.
2 - For a lot of purposes, it isn't sufficient. However, the decision should be based on an assessment the risks, and balancing risks versus the cost / severity of the consequences of security failure.

SOAP security: password param good enough?

I've got 2 backends that need to share information between them using SOAP services across the Internet. Theses services are designed to be only used between these 2 backends so I need to secure them.
I've been reading about securing SOAP APIs but in this instance wouldn't a 'password' param in each method of the API be enough? The password would be hardcoded in each backend and verified at each call against the hardcoded one.
There are 3 methods total so implementation would be easy enough. Also, both points are server sided (client calls one point of the backend, not the SOAP API) so I guess hardcoding the password isn't that terrible.
Does this implementation pose any security risks? Would it be worth it to do it any other way?
Server backend is Spring + CXF.
Thanks!
A way to implement this is using Public key cryptography. This allows you to share a public key with the other side to encrypt the messages send. The message can then be decrypted with the private key. more in the wiki entry above.
java doc
Tutorial
All these links on the subject where done with a quick google search so you should be easly be able to find more examples on this subject by googling:
java public key encryption tutorial

What's the best way to get credentials in a JAX-RS Application?

I'm working on a small piece of middleware based on RESTlet that's providing a REST API to several back-end systems.
There for, my JAX-RS Application requires credentials for some of its methods to authenticate calls to back-end systems using (clear text) user name and password.
So far, I found a lot of documentation on Authorization/Authentication, but all of it only goes as far as validating access to methods and providing user groups. None of it seems to give me the possibility to pass the users' credentials to the actual methods. Is there a nice way to inject them without being REST framework dependent?
A common (and not very secure unless you're on HTTPS) strategy is to put them in the HTTP Request Header if you just want plain authentication. On the server side you can use those values and do whatever you want with them, including evaluating access to the requested service. If you use JAX-RS is relatively simple to create a utility method that does that.
If you also want to ensure integrity you may want to include an hash obtained hashing the concatenation of all param string representation with a simmetric key (known both by client and server). On the server side you recompute the hash to check if the request has been tampered or not. In this way even if an eavesdropper get your credentials sniffing the netwkork traffic he would have difficult times in sending fake requests or tampering a correct one.

Web App Authentication for REST API Backend

I am currently in the early stages of creating a web application (HTML5, JS, etc.) that uses a REST API on the backend (Java, specifically Jersey v1.18). The nature of the data that will be stored is highly sensitive, so security is something that I’ve started looking at, even though the application is only in the early stages. The eventual goal will be to have native mobile applications as well, and to potentially provide access to the data for external clients via the same API.
In my research thus far, I have identified a variety of authentication methods, including HTTP Basic, token-based, session cookie, OAuth, HMAC, etc. The key component here is that the REST API will be primarily accessed by users, rather than other applications or backends. Thus, having a “login/logout” equivalent is important, and this boils down to user level authentication.
So far, HMAC authentication looks to be the most promising, as we have no plans to integrate with any OAuth provider at this moment.
I have already read through dozens of SO posts, as well as articles such as:
http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/
http://www.errant.me.uk/blog/2013/04/authenticating-restful-web-applications/ (note: this is clearly bad, as salting with the username is not recommended)
Ideally, HMAC seems like the way to go, but I have yet to see a recommended approach to handling the shared secret. The idea of using a resource to validate credentials, which then provides a token/nonce to be used with the HMAC scheme, seems to be an option, but I’m questioning the advantages over just using this token/nonce strictly as a token.
I know that HMAC authentication for a REST API has been discussed at length, but when used in conjunction with the authentication details that users have come to expect (username, email, password, etc.), is there any recommended approach that doesn’t require a pre-shared secret key?
This is primarily an opinion-based question, but I'll offer my two cents: just go for a session cookie.
If your primary audience is humans, and you don't need to integrate with third parties, don't bother with OAuth. Just make sure your API is only available over HTTPS, and issue a session token that the server can revoke after login. Strictly speaking it doesn't need to be a cookie; I've seen APIs that stash the token in HTML5 session storage and provide it in the Authorization header or as a query param.
If you have SSL set up properly, your users will get the expected padlock in the browser, and you'll be safe from anyone in between you and the client. If the client is compromised, you're screwed anyways. And since the client can't keep a secret, there aren't a lot of advantages to more complex HMAC schemes.

Encrypt/ Secure communication Android app <-> REST webservice

I want to create a backend for my android app with Tapestry5 and this http://code.google.com/p/t5-restful-webservices/ plugin.
The app will communicate with the server by calling REST methods both for registered users (that would be easy to secure I guess) as well as unregistered users.
Now of course I don't want people to just call that webservice from a browser.
How can I make sure that only my app can make calls to this backend?
I can think of 2 approaches:
Use SSL to secure the connection. SSL can do a handshake checking the credentials.
To authenticate the user you can use a certificate or a PSK.
Or you can simply create a Hash (SHA or MD5) of your data and include a key. This is called hmac. A reverse engineer may get the Key cause you have to hardcode it in your code.
checking for the users UA could help...

Categories

Resources