I am using WSO2 Identity Server v5.6.0.
I want to encrypt usernames and emails saved in the database.
The documentation says that as a part of Personal Data Protection WSO2 IS is hashing the user credentials:
But, in the tables such as IDN_OAUTH2_ACCESS_TOKEN
IDN_IDENTITY_USER_DATA the UserName column contains data in plain text.
My Question is:
How to encode or encrypt the UserName column to make the personal data more secure?
Or Broadly, How can I have WSO2 encrypt some information before storing it in the database?
The documentation says that as a part of Personal Data Protection WSO2 IS is hashing the user credentials
The user's password is hashed by default using the default userstore, you may see
http://xacmlinfo.org/2015/06/10/user-password-hashing-with-wso2-identity-server-wso2is/ For other userstore types it all depends on underlaying implementation (e. g. LDAP)
As well it is possible to encrypt an access token, see https://docs.wso2.com/m/mobile.action#page/85392668
How to encode or encrypt the UserName column to make the personal data more secure?
Or Broadly, How can I have WSO2 encrypt some information before storing it in the database?
You can have it easy or hard way.
Easy - using the JDBC userstore you may configure "advanced" properties and define your own SQL commands to update or query data (including encryption of data). https://docs.wso2.com/m/mobile.action#page/87705730
More complex - you may create your own userstore implementation https://docs.wso2.com/m/view-rendered-page.action?abstractPageId=92523884
I am unfamiliar with WSO2 but:
1) Hashing is not the same as encryption. Hashing is (ideally) not reversable, and that's the point. Encryption is a reversable hash where the source (plaintext) can be recovered.
2) The username might be the reference needed by WSO2 to decrypt or cross reference the data given in any hash (or encryption). I hope not, but....
3) The encryption/hashing may well take place when the data is in transit rather than when the data is at rest. If you are looking in your data storage depository and seeing plaintext usernames this may well be simply because in storage on your server (or elsewhere) the data is not covered by the WSO2 encryption/hashing mechanism.
- Are other fields in your database table hashed?
- Can you see any [other] non-hashed output to your endpoint browser (ie end user)?
4)
[I want to] make the personal data more secure
How will encrypting usernames help with that? What sort of data theft will that prevent? There are different ways of protecting different data from different threats; exampled by hashing (as outlined in the linked document) being completely different from encryption (as you request you want to achieve).
If you can answer the above that would help a lot. Thank you.
Related
I want to secure remember me token for my website. I have read many articles but all points to one thing that to map those two tokens in database. Is there any other way that can be used to secure the token without using database?
You could use public key cryptography to sign the information on the server and then ask the browser to store that information as a cookie. You never need to share the private key to any clients for that. When restoring the session based on the cookie, the server can then verify the signature.
You could also encrypt the contents of the cookie with the same or a different key. Then only the server is able to decrypt what is stored in the browser, therefore even sensitive data can be sent there.
The most popular algorithm is RSA, but you should check out ED25519 that seems to be independent of any surveillance companies and organizations.
I have setup an web-based API to allow a remote app to GET/POST data. Every API call is authenticated with a User ID and Password that is encrypted with a secret key known only to the remote app and the website. This authentication not only ensures that the user can access the API, but also allows me to implement security features based on the user's profile (i.e. User A can see items A & B, but not item C).
I would like my server-side website pages to be able to call the same API methods remotely via AJAX calls, but, something just doesn't seem right about storing encrypted passwords in the code, and, my website implements a "Login As" feature, which will not allow me to set the encrypted password, since the passwords are not stored in plain text.
What is a good way to implement API security for both remote and "local" calls that doesn't require encrypting the user's password?
You should not be storing usernames and passwords in server side code. Sooner or later someone will lay eyes on your code and your data will be vulnerable.
But you should also not be storing secrets (key) in client side code. You should not assume your client can be trusted to keep that secret.
Giving user A access to item A and B, but not C is called authorization and depends on you knowing who calls your API (authentication).
You should probably look into a authentication protocol like OpenID Connect and an authorization protocol like OAuth 2.0.
Also see my answer to this question.
I need to create an application for a company and they would like to have people login to the application to have different permissions to perform different tasks.
My initial idea was to create a MySQL database, hardcode the credentials into the application and have the application connect to the MySQL database. The MySQL database would then have a table called "users" which would store usernames, passwords and permissions. The application would then query the server and perform the authentication.
The biggest problem with this is having the MySQL credentials hard coded into the application. If the application gets into the wrong hands, they could do lots of damage to the MySQL database if they snoop around to find the credentials and start dropping tables.
So I thought of developing a server that acts as an interface for the MySQL Database. For example, the client application would connect to the Server via TCP, and the server connects to a MySQL database. That way the MySQL credentials are never exposed to end-users. However, this means I have to develop a server application which a) will be harder to maintain and deploy for my customer (as opposed to just setting up a MySQL Server) and b)Has potential to introduce more bugs since I have an additional system I need to make (which relates back to point a for deploying bug fixes, etc)
So I was thinking instead of having a table of users in the database and having the application connect directly to the MySQL server with hardcoded credentials, the end-user would be given actual MySQL user credentials in which they would enter into the application to connect to the MySQL server. This means if someone gets their hands on the application, they can't do any damage to the MySQL database, but there still remains the risk of an end-user giving their credentials to the wrong person.
What are the best ways to have a desktop application connect to a MySQL database? Are there any other solutions other than the 3 I have thought of, or do you have any thoughts on my solutions?
As #Perception noted. Your best bet here is to implement a web service in front of MySQL. You don't want unknown numbers of clients from unknown IP addresses all having access to your database.
It would be really easy to DOS attack you by tying up MySQL connections. Not to mention that you would very severely limit your ability to scale your backend service to meet the demands of an increased client base without having a web service in between.
The web service could also offer you the ability to control user authentication and authorization in any number of ways (user/pass combination, token-based access, OAuth access, etc.).
Where I work there are two practices I have seen:
Each entity (person, thing, or business (depending on level of granularity needed) accessing the database) has their very own credentials. This was used on an MSSQL and on a Rocket Universe database. This is mostly the retail and legacy software.
We host the application ourselves and use a separate authentication system for users. The database credentials are stored on our server where the application is hosted. The client knows nothing of the backing database. These are usually web apps and web services.
Something you could do that we have done is that many of our applications actually talk through a RESTful service that emulates the database in a way. The application itself has no access to the database. I would read the wikipedia article on restful services for more information. Our authentication is done using Nonce encoded HMAC requests where each user is given their very own key tied to their credentials.
Wrapping the database in a web service gives you a few possible advantages:
If you decide to change your database structure while keeping the same information, you might not even need to update the client applications, just the service.
Credentials never leave the server, your credentials remain safe so long as nobody gains access to your server. Security in general is increased.
If you do your service cleverly enough, you could even transfer much of the internal logic that would normally be client side onto the server, making updates and bugfixes virtually seamless to the client.
The disadvantages that I see:
It is one more thing to maintain
Your application is vulnerable to denial of service attacks, but since it is a database that's a possible problem anyway
If the server goes down, all the client applications go down, but again, still a problem anyway.
RESTful architecture: http://en.wikipedia.org/wiki/Representational_state_transfer
HMAC: http://en.wikipedia.org/wiki/Hash-based_message_authentication_code
Our HMAC system works like so:
User logs in using username and password to their local application.
The local application communicates to our authentication service and gets a "Session Key" and shared secret for that username and password.
Using the Session Key (which expires in a short period of time), the application creates an API Key (which lasts a long time) and stores it to the computer. The session key could be used instead of an API Key if the user is required to log in each time. We mainly did it this way for convenience for some programs. If the computer is not secure, the Session Key should be used only and no API key is stored on the local machine. Each time the user logs in, they get a new Session Key.
Each request to the database service is accompanied by a HMAC-signed nonce which the application gets from the authorization service based on the API key. After getting the nonce, the application signs it using the shared secret. These signed requests can only be used once since the web service (which the user could know nothing about) authenticates the request. Once the signed nonce has been authenticated server-side by seeing if hashing the nonce with that particular API/Session Key's shared secret results in the same digest, the nonce is marked expired and the request is granted.
The above is vulnerable to man-in-the-middle attacks if HTTPS is not used, so often people make a message based on the nonce and the URL being requested along with a timestamp and compute the HMAC on that. The server then recreates the message based on the URL, checks to see if the timestamp is within some bounds (+/- 4mins or something), and then authorizes the user based on that information.
To further granulate operations, we also have a role system which checks to see if the user who owns the Session/API Key has been given permission to request the thing that they were requesting. If they have the appropriate role, the request is granted.
Summary: Credentials are done user-by-user, the end user has no knowledge of the database, a web service wraps the database in a RESTful API, and a role based system is used to make permissions granular.
This is just a suggestion and I am not saying this is the best or only way to do this. This just happens to be how we have ended up doing it where I work.
Let's look at two ways of dealing with database:
Client directly connects database, and manipulate database
Server connects to database and provide interface for client to use
Considering your use case:
valid valid serial number or to store/read information about certain user
it can be designed in the following way to provide security. (I'm no expert in this)
Client directly connects database, and manipulate database
You don't have to use your admin to visit database, instead you create a user for client only, and limit user's access privilege to only viewing (certain data). And you can enforce security policy at database by changing privilege for this user.
you can consult MySQL :: MySQL 5.1 Reference Manual :: 6 Security for more info.
6.2 The MySQL Access Privilege System
6.3 MySQL User Account Management
Server connects to database and provide interface for client to use
You can use HTTP and provide interface to client to use. And only the backend connects to the database.
Something like RESTful API, there are many easy to use framework that provides authentication and authorization.
I don't think it's good idea to let client have direct access to database in your case. So if possible, the second option is better.
Also note that password based authentication is not ideal.
I just read about how access keys and secret ids could be used to send authenticated requests to a RESTful webservice. However, I dont understand the advantages of using it over other alternatives(such as sending over the username and password, for instance), assuming that all communication with the server is over HTTPS.
What are the advantages of using such a mechanism?
Thanks.
Access key is roughly equivalent to a username, and access secret is roughly equivalent to a password. The access key makes it possible for the service to figure out who you are, and the access secret affirms that it's really you ("you" being your site in this context). The access key is not sensitive, and it is usually okay to be published in frontend code (Javascript, links in HTML, etc), while the access secret you need to keep, well, secret, because otherwise other people/sites will be able to impersonate your requests to the service. There is not much difference between key/secret and username/password scheme; the main difference is that key and secret are usually randomly generated by the service, which prevents people from using values like "default/12345" and similar nonsense.
Some existing web services I consume have methods that look something like this:
List<Employee> employees =
employeeService.GetEmployees(accessKey, allDepartments);
The accessKey serves two purposes; it acts as both authentication and identification. Only valid access codes are responded to (authentication) and it services as a link to a particular client's data.
If the services were to be done a restful manner I'm not sure how this would be achieved. I definitely would not want to do something like this:
http://www.business.com/<GuidHere>/Employees/
Since this would show the accessKey, which is somewhat secret, (ie, its usually in an encrypted file on the client which uses this) we can't show the GUID in a URI. How is something like this achieved using a restful architecture?
You could send the authentication token using HTTP headers.
If this is a RESTful web service I'm assuming it's being consumed by a machine so why not pass the access key in the url?
At then end of the day you need to put it somewhere and hiding them in hidden form fields in the browser (if the service is to be browsable) isn't much in the way of security.
If the key is so sensitive, why not symmetrically encrypt on the server per session and pass that value around instead?
Just some thoughts.
Kev
If time isn't an issue implementing OAuth security may be useful. OAuth uses a public key, and also a secret. The mess is hashed (in most cases) and the server will use the public key + it's copy of the secret to do the same hashing and make sure its result matches the requests.
The benefit is you wouldn't need to use HTTPS or POST. Get* REST api methods should be using the HTTP GET method (I'm not sure if being RESTful is your goal, just thought I would point that out). I agree with Mr. Pang, use http://www.business.com/employees. The query string could contain the list of department ids.
For your case the service call wouldn't have the 'accessKey' argument, rather it would become the public key (I imagine) and be used in either the headers, query string, or as a POST param.
Some good info on OAuth: http://www.hueniverse.com/hueniverse/
As Troy Alford pointed out, my original suggestion was incorrect. You shouldn't be using POST in a situation like this. You should use a GET request with the authentication information in the HTTP headers. Take a look at basic access authentication for one way to do that.