Encrypting the database at rest without paying? - encryption

Right now the only way to encrypt a Cassandra database at rest seems to be with their enterprise edition which costs thousands of dollars: How to use Cassandra with TDE (Transparent Data Encryption)
Another solution is to encrypt every value before it enters the database, but then the key will be stored somewhere on every server in plaintext and would be easy to find.
I understand they offer "free" use for certain companies, but this is not an option and I am not authorized to pay $2000/server. How do traditional companies encrypt their distributed databases?
Thanks for the advice

I took the approach of encrypting the data disk on AWS. I added a new volume to the instance and checked the option to encrypt the volume. Then I edited cassandra.yaml to point to the encrypted volume.

We have done similar requirement in one of our project. Basically, I made use of trigger feature in Cassandra with custom implementation to perform encryption. It seems to be working fine for us.
You can refer below docs on how to create trigger and sample implemention of ITrigger interface
https://docs.datastax.com/en/cql/3.3/cql/cql_reference/cqlCreateTrigger.html
https://github.com/apache/cassandra/blob/2e5847d29bbdd45fd4fc73f071779d91326ceeba/examples/triggers/src/org/apache/cassandra/triggers/AuditTrigger.java

Encrypting before inserting is a good way. The keys will either be on each application or on each cassandra node. There isnt much difference really, either way you should use filesystem permissions to restrict access to key just the apps user. Theres steps to get more secure from there like requiring entering of passphrase on startup vs storing on disk, but it makes operational tasks horrific.

Related

Protecting local proprietary data in an Xamarin app

I have a Xamarin.Forms app that uses a local SqLite database as its source for data. The data is proprietary, so I want to protect it so that if someone gets access to the database file, they would have to decrypt it to access the data.
I also want to limit the number of queries users can make against the database so that at a certain point they have to purchase the ability to use more of the data (in-app purchase).
I want to avoid making network calls as much as possible to minimize impact to the user's data plan and allow the app to work well in conditions where there is poor or no connectivity. So, I want the data stored in a local database (perhaps in SqLite).
I'm curious how different people would approach this problem to protect the data and at the same time minimize network usage.
Here is kind of what I was thinking (if it's possible):
1) Let the user download/install the app.
2) On first load, the app will upload a key based on the device id and the user's current purchase information. Then it will download a SqLite database file that has been encrypted using the uploaded key.
3) When the user reaches their limit of queries, the database file is deleted. If they purchase more data, then a new key is uploaded and a new encrypted database is downloaded to be used.
Thoughts? Is there a better way?
I would suggest SQLCipher! It is a Component within Xamarin (http://components.xamarin.com/view/sqlcipher-for-xamarin-ios) but can also be built from source as it is Open Source (https://www.zetetic.net/sqlcipher/open-source/)
That will totally secure your database :)
UPDATE 8/2/2018 - SQL Cipher is now free and easy to implement thanks to the greatness of Frank Krueger. sqlite-net (https://github.com/praeclarum/sqlite-net) is the defacto sqlite library for Xamarin now (if you're still using the Sqlite.Net fork I recommend going back to sqlite-net as soon as possible as Sqlite.Net has been abandoned) and it now includes SQL Cipher support completely free of charge.
As clb mentioned, SQLCipher is open source. So if you don't want to pay for the component you can download and build the source yourself, then wrap it for use in Xamarin. This is, admittedly, a technically challenging task.
If that's not an option, I would recommend two other options:
Reevaluate your need to store data locally. It's extremely unlikely that you need to transfer enough data to even cause a blip on a user's data plan. And between cellular and wifi, it's not that common anymore for users to be without a connection. It certainly does happen, and there are certain apps where this is very important, but you may have to make concessions if the data is that sensitive.
If you absolutely have to store the data locally, and you can't use SQLCipher, your last real option is to use a cryptography library and encrypt the data itself, rather than the database file. This is less than ideal, typically, for a variety of reasons, but it may be your last resort. PCL Crypt is a PCL capable crypto library that you can look into.
https://github.com/aarnott/pclcrypto

Encrypting fields in openerp using db postgres

We are going to store some sensitive information about our customers in the db model res_partners.
However we don't want to store this information in a simple text field. We would prefer
some basic encrypting if possible for those fields. We do not want someone who
has access to the db to have access to these fields.
Is there a way we can get this done in openerp or postgres ?
Thank you,
Vishal Khialani
There is no such thing as "basic" encryption. Rot13 is not getting to get you anywhere here. If your data is sensitive enough to deserve protection, then you need to use state of the art cyphers such as Blowfish. I advise you give a good long look at Bruce Schneier's book Applied Cryptography
The easy (and insecure) way to achieve this is to overload the write and read methods of your model to encrypt before writing and decrypt after reading.
The tricky part is storing the encryption key. You could store it in a file on the computer running the OpenERP server (assuming the database is running on another server). This is still pretty weak, as the key will be available in clear on the server, but could still be useful if you don't trust your database server admin, but do trust you openerp server admin. It's still way easier to get the database server in a secure and trusted place, and if required to crypt offline copies of the database (such as backups).
If you want more security, you'll have to send the data encrypted to the client application, and let the decryption happen there, using a user-supplied key. I'm not enough knowledgeable of this part of openerp to say if it is easily feasible or not.

EncryptByKey versus EncryptByPassPhrase?

What are your thoughts about SQL Server's symmetric key functions? Specifically, I have two questions:
Which set of functions is better... EncryptByKey or EncryptByPassPhrase?
Both functions require a passphrase of some kind. In a typical web-application architecture, where should this passphrase be stored? (i.e., hard coded within a stored procedure in the database, or stored as a configuration setting in the web application)
I'm eager to see what the best practice is for these functions.
Encrypting using a passphrase is easier but the advantage of using a key is that the key can be secured using built in SQL sever roles. You can lock down use of the key to only those users that require access to that data.
If you use a certificate then you only need plain text during the initial setup and can store it outside your system. Again, the certificate is a securable object and can be locked down.
Hope this helps.

Best Practice: Protecting Personally Identifiable Data in a ASP.NET / SQL Server 2008 Environment

Thanks to a SQL injection vulnerability found last week, some of my recommendations are being investigated at work. We recently re-did an application which stores personally identifiable information whose disclosure could lead to identity theft. While we read some of the data on a regular basis, the restricted data we only need a couple of times a year and then only two employees need it.
I've read up on SQL Server 2008's encryption function, but I'm not convinced that's the route I want to go. My problem ultimately boils down to the fact that we're either using symmetric keys or assymetric keys encrypted by a symmetric key. Thus it seems like a SQL injection attack could lead to a data leak. I realize permissions should prevent that, permissions should also prevent the leaking in the first place.
It seems to me the better method would be to asymmetrically encrypt the data in the web application. Then store the private key offline and have a fat client that they can run the few times a year they need to access the restricted data so the data could be decrypted on the client. This way, if the server get compromised, we don't leak old data although depending on what they do we may leak future data. I think the big disadvantage is this would require re-writing the web application and creating a new fat application (to pull the restricted data). Due to the recent problem, I can probably get the time allocated, so now would be the proper time to make the recommendation.
Do you have a better suggestion? Which method would you recommend? More importantly why?
Encryption in SQL is really only good for securing the data as it rests on the server, although that doesn't mean that it is unimportant. When you mention that a prime concern is injection attacks or the likes, my concern would be whether or not the database uses a single account (SQL or otherwise) to connect to the database, which would be common for a public internet site. If you use integrated authentication, or connect to SQL using the same credentials supplied to the application, then SQL's encryption might work fine.
However, if you're using a single login, SQL's encryption is going to manage encrypting and decrypting the data for you, based on your login. So, if your application is compromised, SQL may not be able to protect that data for you, as it implicitly decrypts it and doesn't know anything is wrong.
You may want to, as you suggested, encrypt/decrypt the data in the application, and store as bytes in the database. That way you control who can decrypt the data and when (for example, you could assign the key to decrypting this data to those few employees you mentioned that are in a specific role). You could look into Microsoft's Security Application Block, or Bouncy Castle, etc. for good encryption utilities. Just be careful about how you manage the key.
Update:
Although you could potentially use two connection strings: one normal, with no rights to the encrypted data, and one that has the key and the rights to the data. Then have your application use the appropriate connection when the user has the rights. Of course, that's pretty kludgy.
Some practices that we follow:
Never use dynamic sql. It's completely unnecessary.
Regardless of #1, always parameterize your queries. This alone will get rid of sql injection, but there are lots of other entry points.
Use the least priviledged account you can for accessing the database server. This typically means the account should NOT have the ability to run ad hoc queries (see #1). It also means that it shouldn't have access to run any DDL statements (create, drop, ..).
Don't trust the web application, much less any input received from a browser. Sanitize everything. Web App servers are cracked on a regular basis.
We also deal with a lot of PII and are extremely strict (to the point of paranoia) on how the data is accessed and by whom. Everything that comes through the server is logged. To make sure this happens we only allow access to the database through stored procedures. The procs always test to see if the user account is even authorized to execute the query. Further they log when, who, and what. We do not have any mass delete queries at all.
Our IDs are completely non-guessable. This is for every table in the system.
We do not use ORM tools. They typically require way too much access to the database server to work right and we just aren't comfortable with that.
We do background checks on the DBA's and our other production support people every 6 months. Access to production is tightly controlled and actively monitored. We don't allow contractors access to production for any reason and everything is code reviewed prior to being allowed into the code base.
For the encrypted data, allow specific users access to the decryption keys. Change those keys often, as in once a month if possible.
ALL data transfer between machines is encrypted. Kerberos between servers and desktops; SSL between IIS and browsers.
Recognize and architect for the fact that a LOT of data theft is from internal employees. Either by actively hacking the system, actively granting unauthorized users access, or passively by installing crap (like IE 6) on their machines. Guess how Google got hacked.
The main question in your situation is identifying all of the parts that need access to the PII.
Things like how does the information get into your system? The main thing here is where does the initial encryption key get stored?
Your issue is key management. No matter how many way's you turn the problem around, you'll end up with one simple elementary fact: the service process needs access to the keys to encrypt the data (is important that is a background service because that implies it cannot obtain the root of the encryption hierarchy key from a human entered password whenever is needed). Therefore compromise of the process leads to compromise of the key(s). There are ways to obfuscate this issue, but no ways to truly hide it. To put this into perspective though, only a compromise of the SQL Server process itself could expose this problem, something which is significantly higher bar than a SQL Injection vulnerability.
You are trying to circumvent this problem by relying on the public key/private key asymmetry and use the public key to encrypt the data so that it can only be decrypted by the owner of the private key. So that the service does not need access to the private key, therefore if compromised it cannot be used to decrypt the data. Unfortunately this works only in theory. In the real world RSA encryption is so slow that is cannot be used for bulk data. This is why common RSA based encryption scheme uses a symmetric key to encrypt the data and encrypts the symmetric key with the RSA key.
My recommendation would be to stick with tried and tested approaches. Use a symmetric key to encrypt the data. Use an RSA key to encrypt the symmetric key(s). Have SQL Server own and control the RSA private key. Use the permission hierarchy to protect the RSA private key (really, there isn't anything better you could do). Use module signing to grant access to the encryption procedures. This way the ASP service itself does not even have the privileges to encrypt the data, it can only do so by the means of the signed encryption procedure. It would take significant 'creative' administration/coding mistakes from your colleagues to compromise such a scheme, significantly more than a mere 'operator error'. A system administrator would have an easier path, but any solution that is designed to circumvent a sysadmin is doomed.

Encrypt data from users in web applications

Some web applications, like Google Docs, store data generated by the users. Data that can only be read by its owner. Or maybe not?
As far as I know, this data is stored as is in a remote database. So, if anybody with enough privileges in the remote system (a sysadmin, for instance) can lurk my data, my privacy could get compromised.
What could be the best solution to store this data encrypted in a remote database and that only the data's owner could decrypt it? How to make this process transparent to the user? (You can't use the user's password as the key to encrypt his data, because you shouldn't know his password).
If encryption/decryption is performed on the server, there is no way you can make sure that the cleartext is not dumped somewhere in some log file or the like.
You need to do the encryption/decryption inside the browser using JavaScript/Java/ActiveX or whatever. As a user, you need to trust the client-side of the web service not to send back the info unencrypted to the server.
Carl
I think Carl, nailed it on the head, but I wanted to say that with any website, if you are providing it any confidential/personal/privileged information then you have to have a certain level of trust, and it is the responsibility of the service provider to establish this trust. This is one of those questions that has been asked many times, across the internet since it's inception, and it will only continue to grow until we all have our own SSL certs encoded on our fingerprint, and even then we will have to ask the question 'How do I know that the finger is still attached to the user?'.
Well, I'd consider a process similar to Amazons AWS. You authenticate with a private password that is not saved remotely. Just a hash is used to validate the user. Then you generate a certificate with one of the main and long-tested algorithms and provide this from a secure page. Then a public/private key algorithm can be used to encrypt things for the users.
But the main problem remains the same: If someone with enough privileges can access the data (say: hacked your server), you're lost. Given enough time and power, everything could be breaked. It's just a matter of time.
But I think algorithms and applications like GPG/PGP and similar are very well known and can be implemented in a way that secure web applications - and keep the usability at a score that the average user can handle.
edit I want to catch up with #Carl and Unkwntech and add their statement: If you don't trust the site itself, don't give private data away. That's even before someone hacks their servers... ;-)
Auron asked: How do you generate a key for the client to encrypt/decrypt the data? Where do you store this key?
Well, the key is usually derived from some password the user has chosen. You don't store it, you trust the user to remember it. What you can store is maybe some salt value associated to that user, to increase security against rainbow-table attacks for instance.
Crypto is hard to get right ;-) I would recommend to look at the source code for AxCrypt and for Xecrets' off-line client.
Carl
No, you can't use passwords, but you could use password hashes. However, Google Docs are all about sharing, so such a method would require storing a copy of the document for each user.

Resources