OpenAM: RESTFUL API - Encrypt/Encode Password - openam

We are using the Open AM Restful API to perform authentication. Our restful call has the following format:
http://OpenAM_Host:Port/deploy_uri/identity/authenticate?username=scott&password=tiger
How can we send the password in an encrypted/encoded format?

This is not possible currently out of the box, you need to implement an
own DataStore (if you use the DataStore auth module) or an authentication module which will use symmetric decryption on the supplied password.

You could also enable HTTPBasic Auth module on a chain and send the username/value pair base64 encoded. Not encrypted, but encoded at least (along with special character support).

From what I've found, OpenAM does not provide this support out of the box. Based on information from the OpenAM mailing list, there are two options:
Option 1. SSL and POST
The most common solution is to make use of SSL for encryption.
Option 2. Custom Login Module
If you need to encrypt your password with a given algorithm, then you will need to create a custom login module. You will encrypt the password before making the restful call and then the login module with decrypt the password. In this scenario, you do not need SSL.

Related

Jwt strategy with ES256k algorithm (not supported ?)

I have an authentication microservice which sign a jwt using ES256k algorithm, when I try to use this token to call an API from a separate microservice with jwt strategy/guard, it doesn't work cause I guess ES256k is not a supported algorithm.
So is there a way to customize the verification to use a service or a function to verify tokens in a certain way? Or I'm I missing something?
you most likely use some provider like Auth0 or Cognito or OneLogin
these guys use sets of JWT to support multiple accounts, this is called JWKS
If my guess is correct your best choice is jwks-rsa library by Auth0
you can check a list of supported algorithms here
and as your question has label nestjs, you can try to use my boilerplate

How to securely pass the API Key in the HTTP Header?

I am building a API suite to connect to our application. Each user will have an unique API key which will be passed in the Header.
I am here to ask, what is the best way to authenticate the user? I donot want the user to pass the API key without any encryption ?
I am passing the API key like this :
$headers['x-axpr-auth'] = '<API-KEY>';
Since, I am building the API myself, I have the flexibility to use different encryption/authentication techniques.
Using HTTPS is pretty much mandatory in this case so I'm going to assume you (will) do that.
If you have an API key with long-term validity, then you should consider using some kind of "temporary token" with (very?) limited validity - so the attack window is much smaller.
This is similar to using Basic Authentication (sending password with every request) versus sending credentials only once and using session cookie afterward.
You should look at existing authentication/authorization schemes - OAuth2 (with access and refresh tokens) may be relevant since you're building APIs. OpenID Connect builds on top of OAuth2 and provides a proper authentication layer.
Apart from that, it's uncommon to explicitly encrypt API token in an HTTP header, since the whole communication is already encrypted using HTTPS.

Validate LTPA token in nodejs

IS there any way to validate LTPA token previously generated from IBM Tivoli federated Websphere Application Server in my nodejs application.
I have checked "ldapjs", but I could not find something to validate LTPA token.
I have written a small library for this purpose: https://www.npmjs.com/package/ltpa
Once you've extracted your server key you can use the library to validate, and generate LtpaTokens.
There is an Java API related with WSLogin - which allows to validate LTPA. (Technically a re-login here)
But I dont think you can use this with Nodejs.
But my preferred way is to use the BASIC authentication using the URL post from your app.
This requires a provider (Websphere) to expose a URL for you.

How to secure my REST-API?

I have an api build with node.js & express.js. For now I have a unsecured api where anyone can GET,POST,PUT,DELETE records.
I am facing following problem. My rest api should not authenticate users but applications. E.g. my mobile application should have a valid token to access the api. Same for web application.
Another user case: my api will be used by another application that only uses one single rest call. So somewhere in the code I don't know in an application I don't know (for most part) a rest call on my api will be triggered. How can I secure such access, since no cookies or sessions are involved?
My first thought was, create a user and a password. Each api call (via https) must contain the credentials. Password may be hashed. However I read this
Usernames and passwords, session tokens and API keys should not appear
in the URL, as this can be captured in web server logs and makes them
intrinsically valuable.
from https://www.owasp.org/index.php/REST_Security_Cheat_Sheet
Any suggestions on this? I read about oauth but this involves redirections and I cannot imagine how this would work with a mobile app e.g. on android.
You can use RSA encryption for this, have a look at ursa module for node.
A simplified process of using this is... Arrange you client applications to encrypt a secret password with a public key and on the server side decrypt it with a private one, check if the secret is what you expect and act accordingly...
There are plenty of articles about using rsa in applications, I am sure you will be able to pick up a more definite explanation of how to work it if you just google.
EDIT
I have just bumped into this post which has a more detailed write-up on this question.
There is a question of how applications get to know a username/password in the first place, but if you are OK with the general idea (which is safe, as long as you consider the environment in which the application runs to be safe), then you don't need to worry about username/passwords in URLs: simply use https instead of https.
https is encrypted so that only the 2 endpoints (the client and your API) can read even the URL. Any router/proxy/server in between sees only encrypted data and has no means of accessing your username/passwords.
Instead of a username/password, btw, just use an "Access Token", which is a long (read: hard to guess) string, and assign one access token per application. In your end, you keep the list of valid tokens in a DB, and authenticate against that. You can even attach expiry dates to those strings, if you wish so.
Adding access token as part of an https:// url is common practice.

How should I savely store encrypted user data on my server, and serve it only to the right user?

Let's assume I must store user's sensitive data, which was optionally encrypted on the client side.
Encryption (optional) should be done with user's passphrase.
User login (optional) should be done with user's password.
Notes:
A plain-text password is not stored on the server or transferred over the network.
My options and their drawbacks:
1. No authentication, Client-side authorization:
The server gives the data to everyone, but only the original user have the means to decode.
Data can be used by anyone to try to crack the encryption - not the best way to secure it.
2. Server-side authentication, no authorization:
Server stores user's password to access the data, and only gives the data to the user that can provide the right password.
Users don't trust the network for transferring their data without encryption.
3. Authentication and authorization:
Server stores user's password to access the encrypted data, the encryption is done using the passphrase that is different from user's password.
Good security, but users don't want to remember two passwords.
4. Authentication vs. Authorization:
Server stores user's password to access the encrypted data, the encryption is done using the same password.
Users are happy. Some security concerns.
I prefer the latest fourth option, but my concern is:
What if the server will get compromised, how can I be sure that encrypted password and encrypted data can't be used together to break the encryption?
How can I make it harder to break the encryption?
Some thoughts:
Use different encryption algorithms for password and data.
Add fixed string to the end of the user's password before encryption.
Pad user's password to some length.
EDIT:
The system should be very similar to a backup system that should be secure from all sides: the server should not be able to read the data, only the original client should be able to access the data and man in the middle attacks should be prevented. So if someone hacks the server authentication or the client encryption, the data should not be revealed.
It should be web based, so the man in the middle attack should be prevented with HTTPS.
To prevent server hacks revealing the data, the data is encrypted in client-side.
To prevent client encryption tampering, the access to the data should be protected on the server side with some log in and password or a token (may be unique URL).
#Vitaly, permit me to clarify some terms before I answer, as you seem to be using a different meaning for some than is commonly used.
Authentication - the process of proving who you are (more accurately, that you own the identity you are claiming).
Authorization - the mechanism used to restrict, control, and grant access.
Encryption - a mechanism for protecting data, even from someone who has access to it.
Now, allow me to rephrase your options, and then I'll suggest something else:
No Authentication, No Authorization, Client-side encryption
Server-side authentication, Server-side authorization, Server-side encryption
Server-side authentication, Server-side authorization, Client-side encryption
Server-side authentication, Server-side authorization, Client-side encryption using server credentials.
Now, I think it can be clearer where each one stands.
In general, you really want to follow the "best practice" (dont get me started on those) principle of "Defense in depth", i.e. dont use only encryption, or only access control, instead use both! But, as you pointed out, this can be in contrast (if the user is required to remember TWO passwords) to another principle, "Keep Security Simple".
Without trying to be TOO annoying, you didn't give much information in the way of your environment. For example, is this e.g. a Web application? If so, why is SSL/TLS not enough encryption for you? Or is this a question of users uploading personal data that you (and your system) should not see either (e.g. a backup-type service)? In which case client-side encryption would be necessary...
So, (finally) my proposed options, depending on your environment / requirements:
If you can, rely on secure protocols (e.g. SSL/TLS) for encryption. Use server-side authentication + authorization, protocol encryption.
If your system needs to further protect this data, e.g. credit cards (note that I am not currently a PCI:QSA ;) ), use the previous option, and in addition server-side encryption using a server-generated encryption key (NOT the password) (and of course protect that).
If the data needs to be protected FROM your system, you will need to do client-side encryption IN ADDITION to server-side authentication+authorization (your option 3 as I restated it).
However, you don't necessarily need to force the user to remember an additional password/phrase. Again, depending on your environment, you might be able to consider some form of key stored on the client, e.g. a certificate in the user's certificate store / keyring, or even stored in a protected configuration file; a key based on biometric data (not easy but i've seen this done successfully, though it has its own set of issues), out of band key distribution (e.g. via cellphone), etc. This would enable you both to use strong keys, prevent the server from accessing those keys, not require the user to remember two keys, and doesn't re-use a single password for different usages in different contexts.
You could take a look at zero-knowledge protocols for authentication, in particular to the Secure Remote Password protocol, which makes it possible to perform password-based authentication without revealing the password to the server. This way the same password can be used both for authentication and for deriving a data encryption key.
Also, you could take a look at the Clipperz online service, which implements something similar to your needs and is also open source.
Use option one and make the URL for the data contain a long random string. Anybody who knows the random string can get the data. Of course, only the client who created the data is going to have that URL right off.
If someone wants to give someone else revokable access, allow them to generate a new random URL and provide a means for them to name that random URL and revoke its ability to get at the data.
Capability based security is easier to get right, more flexible and makes more sense to users. There is a really excellent YouTube video about capability based security and a nice website with some essays about it.

Resources