Encrypt database so system administrators have no access - php

I'm looking to develop an application for healthcare purposes using PHP. I want to encrypt the data so that nobody but the actual users to the application have access to the data.. not even system administrators. Does anyone have thoughts on a process to do this?
I did some research, and this seems possible where one user needs to access his/her data. But, I want to place emphasis on the fact that multiple users will need to access a set of data. Not just one user.
I realize that this could be done with a third common password amongst users, which can act as a salt.. but that doesn't seem very practical :)

To encrypt data use openssl rsa inside a browser. There are some implementation in js available. As fare as I know, the module is not running in every browser.
Store private key inside a local db (html)
encrypt/decrypt data inside browser
build input form with js
save encrypted data then on the server
But in that case even the php appl. has not access to the data :(

Related

How to protect encryption key from server admin?

Scenario
Data is encrypted inside DB using key that is never stored in the app server or DB server
Key is entered upon login and is stored via $_COOKIE['key'] variable for persistence (so user doesn't have to enter it every page load)
Data is decrypted via $_COOKIE['key']
$_COOKIE['key'] is destroyed upon browser exit
Threat
Rouge server admin snoops on PHP files, finds out key is stored at $_COOKIE['key']. He injects malicious code like email_me($_COOKIE['key']);. He erase malicious code after gaining the key.
Question
Is there a way to protect yourself from this kind of scenario?
You can make it harder for a server admin to get the key, but they always can.
Let's think about moving the encryption and decryption to the client side. Now, the server won't get the key, so the server admin should not be able to decrypt the data. That's not quite true, because the server admin can manipulate the page JavaScript so that either the key is sent to the server or nothing is encrypted at all.
The only way a client can be certain that a server admin cannot steal their data, is by using a client software that is open source and cannot be changed on-the-fly by an admin. So, web pages and automatically updating apps are out of the question.
If the key itself is a concern, you can use cryptography oracles like Keyvault in Azure that never release the keys contained within but perform cryptography themselves on data sent to them.
Of course an admin would be able to access the data as long as they have access to the cryptography oracle, but not afterwards, and they would never have the key. This helps in some scenarios, that's the whole point of services like Azure Keyvault. Also you don't need to give actual access to the encryption service to all admins.
Another mitigation (a detective control, as opposed to a preventive one) is audit logging both on the IT and application level. When done right, not even admins can hide the fact that they accessed the data, which again can help mitigate some risks and at least may provide non-repudiation.
Yet another thing you could do is proper change management, controlling who has access (especially write access) to your source code. This can get difficult with script languages like PHP, where you can't really sign code, but you can still have good processes for reviewing and releasing code to production.
So in the end, it's probably less of a technical question, there's a great deal you can do in terms of processes.

Security in data transmission

I'm creating a server(PHP) to store data from android app. With POST query store name, password and email. These data as mentioned are stored on the server (database on hosting).
But I have a lot of questions how to do it correctly:
First is the backend, how to protect data and how to encrypt them?
I know that you can transfer token of android application on the web (server). And there it checked for accuracy, but android application is easy to decompile. How to be in this case?
Also heard of RSA but examples show how the mechanism works. And when used in RSA, I have the private key stored on the server and the public in android application? But what if I we obtain encrypted data from the server on android? I need to decrypt them using the private key. But the key on the server and store the private key on Android ill (paragraph 2, decompiling).
Other...
Please leave comments. Also describe every paragraph of my question, and it is desirable for each paragraph post a link with useful information. Also, I would appreciate any HELPFUL links related to this topic, well, especially your opinion and how best to do it.
I assume that you are trying to create a basic register/login-to-use-this-app mechanism.
Read the PHP FAQ article on password saving on why and how for secure data saving server-side. Basically, to hash (to irreversibly encrypt) sensitive data before directly saving them.
Regarding your second question,
Generally, it is not a big concern on directly transmitting sensitive data between client and server, because there can be these security measures:
Use HTTPS. This will encrypt the stream of data transmission, and it is less vulnerable to the connection being eavesdropped.
You may want to directly send the hash of the password instead of the password itself in the post request, or in other words, use the hash of the user password as the password.
Client frontend
In terms of internal storage, it is not possible to prevent other installed malicious apps from reading and using data you store, unless you (I am not familiar with this) store them in a storage that is only accessible by your own app.
Server backend
There are some servers that distribute OAuth tokens to clients, such as GitHub. However, if you only expect the server login API to be used by your own apps, OAuth isn't necessary in this case, since it is mainly used as a flexible permission bearer which you don't need to concern for your own app.
Instead, the more important thing is how you handle things server-side. For the web API that I once coded for my own server, although I don't expect others to use it, I made the API designed as if it is for the public to use, and pay attention to unexpected client input. This is because clients can be fake anytime, so never trust the integrity of what clients input. (Forgive my obsession, but I even considered backend of my JavaScript on webpages as "clients" to be safe)
I have never used nor have any comprehensive knowledge on other PHP frameworks, but when I work on my website, I would create a safety layer within my own backend code. I separate my backend into two levels, namely the database level and the interface level. The database level should try not let the interface level even get the data that are not supposed to be known by (the current authentication state of) the client, so as to minimize the chance of security vulnerability.
Client-server communication
So this only leaves the problem of data transmission, which is the main point of this question.
As mentioned above, HTTPS would be good enough to encrypt data transmission.
I do not know if this concept is practical, but after initial registration, it might be, if you are obsessive enough, possible to encrypt the data with a timestamp, etc. I am not quite sure about this, but disconnected tokens inspired me on this.
But how much protection you need still depends on what kind of data you are sending. For example, if you are simply tracking user usage, you don't really need a lot of protection for it. Just make sure that the user's original password cannot be leaked by hashing it.

Is storing plain password in session acceptable when using it do decrypt with AES?

I wrote a web app in PHP, which is processing some secret data, placed in one database table. All fields in this table (excluding id and date of creation) are encrypted with AES, so nobody who has got access to this database can read it.
I encrypt that data with user password. There's no plain password anywhere in database, just the SHA1 sum, so I can verify it. However, I need plain password to decrypt user data when he's logged in, so I store this value in session.
Is it OK for this purpose? If not, what are the good patterns to deal with this case?
I encrypt that data with user password
If they change their password you then have to re-encrypt everything. Look into something more static for the key.
so I store this value in session.
The session should not store this type of information as anyone else with a website on the box (or any other way to access the box) may be able to read it. If your box uses something similar to suPHP or phpSuExec (ask your host) you could place this data in a directory that only your account can access. You could even store it back in the database (encrypted of course).
what are the good patterns to deal with this case?
If security is important to you, go dedicated. If you're unable to do that then at least be on a server that uses suPHP or phpSuExec or the like so that your web server processes run under a unique user so that any data related to the encryption key can be secured.
so nobody who has got access to this database can read it.
By storing your password in the session, you will have a lot of session files in your /tmp directory (or wherever they are stored...) containing users passwords.
Not only does access to your server invalidate your first statement (when you have access to the server, you have direct access to lots of passwords), but someone with server access - even a valid server admin like yourself - can see passwords he or she should never be able to see.
So no, this is not OK.
A possible solution to your problem would be to use an encryption key for the user information that is stored on a different server so that access to the database / database server alone is not enough. However, this is just a thought, you might get a better answer to that question on for example https://security.stackexchange.com/

Encrypting user data for automatic login to third party system

I find myself in a situation where I have a set of users on a site who all have stored usernames and passwords that allow them to automatically access third party services via SOAP. The idea is that each user should only need to log in to the main site to gain access to multiple services, using their respective stored user info for each service. I feel like such data should be encrypted in my database when stored and then automatically decrypted when it's passed to the php/SOAP function when the user needs to access a given service. What would be the best way to accomplish this?
I've had a look at AES_ENCRYPT, but it seems as though the encryption and decryption makes use of a key that would have to be stored in my code, in plain text...which doesn't seem like the brightest thing to do. Anyway, this is my first time out on something like this (if you couldn't tell); if you could give me some pointers on how I should approach this, I'd really appreciate it.
Many thanks in advance
You stumbled over the biggest problem with encrypting data in the database:
➽ Where to store the key?
Encryption cannot solve the problem of securing data, it can only "concentrate" it to a key. Wherever you store the key, your application must be able to decrypt the data, so can do an attacker. There are two possible solutions to this problem i know of:
Place the key in a place as secure as you can. That means, it should surely be placed outside of the www-root directory in an inaccessible directory on the server. Depending on the importance of the data, you can also consider to outsource encryption to another dedicated server.
Don't store a key at all and derive it from the user password. This is the only really safe way, because not even the server can decrypt the data then. The cons are of course, that the user needs to enter the password every time he uses your service. If the user changes the password, you need to re-encrypt all data. If the user forgets the password, the data is lost.
P.S. I would recommend to encrypt the data before storing it to the database, because MySQL AES_ENCRYPT uses the ECB mode without an IV. This allows to search for a certain value, but is less secure (i'm pretty sure that you don't want to search by password).

ASP Session Algorithm generate cookie via PHP

I am writing a PHP script that needs to integrate with an ASP.NET login (which happens to be built on Sitecore, not sure if that matters). I need to replicate the ability to generate/login/encrypt a session & data cookie, and also detect if the user is logged in by detecting/decrypting a session & data cookie. Both the PHP & ASP scripts can share the same MS SQL database and are on the same filesystem, so that's not an issue. Most of my issues are just with setting/reading the ASP cookies within PHP.
I have 2 cookies set by ASP.NET,
ASP.NET_SessionId and .ASPXAUTH
It is my belief that the ASP.NET_SessionId is for the session obviously and .ASPXAUTH is for the data.
My questions are:
It is my belief that in order to know if someone is logged in (or login someone in) via an ASP session, in PHP, I will need to compare the session data with the sessions stored on the filesystem, does anybody know where (or what determines where) these are located?
Does anybody know the algorithm used to encrypt/decrypt the ASPXAUTH cookie? I'm aware of the standard "Encrypt" and "Decrypt" methods, but I want to know the code that makes them run precisely. IE is it first some sort of data array that is then salted and hashed? Do the bytes of the output need to be shifted/converted? If so, in what order/way?
I appreciate any assistance, I will award an answer for the person that is the most helpful in answering either of these questions in the next few days.
Currently I have been able to reproduce cookie generation via setcookie() in PHP. That is, I can login via ASP.NET app, take the cookie data, plug it into the PHP app and logout via the ASP .NET app. For those who are going to troll me, I am well aware this is possible and I do not NEED to explain why I am doing this, but it involves a lot of time, money and reasons, so yes, I do need to use BOTH PHP & ASP.NET.
THANKS!
UPDATE
I believe I was partially able to decrypt the cookie using this answer: https://stackoverflow.com/a/988018/775586 Anybody know how to finish it off?
It is my belief that in order to know if someone is logged (or login
someone) in via an ASP session, in PHP, I will need to compare the
session data with the sessions stored on the filesystem, does anybody
know where (or what determines where) these are located?
Nowhere on the file system. By default ASP.NET stores session data in the memory of the application domain. So you can simply forget about accessing this part of the memory from PHP. There are other modes that you could choose which allow you to store the ASP.NET session data either out-of-proc (in a dedicated Windows Service) or in SqlServer. For more information about the different ASP.NET Session modes I invite you to read the following article.
Does anybody know the algorithm used to encrypt/decrypt the ASPXAUTH
cookie? IE is it first some sort of data array that is then salted and
hashed? If so, in what order/way?
It uses the FormsAuthentication.Encrypt and Decrypt methods. They in turn use whatever algorithm and keys you have defined in your machineKey section in your web/machine.config files. For more information about how Forms Authentcation works in ASP.NET I invite you to read the following article.
Okay so for the first question...
ASP doesn't store on the raw filesystem, but can store session data in a database if configured properly and you can specify where. From what I recall reading, this is in a database called "tempdb" or a database which may also have some sprocs in it. More info on that in more plain English here: http://www.codeproject.com/Articles/104082/Configuring-ASP-session-state-on-SQL-server
For the second and more important question:
This amazing article will give you a breakdown of how the ASPX_AUTH cookie is generated and the algorithm to do so: http://www.codeproject.com/Articles/16822/The-Anatomy-of-Forms-Authentication

Categories