I have an application where I want to be able to encrypt large amounts
of text before storing them to my DB (MySQL Text field - might be
switched to a Blob). I have an idea of how to do this, but was
wondering what the general consensus is within the community regarding
the issue.
I have come across a couple different plug ins/gems (Stringbox,
EzCrypto), but am wondering what other people are using. I like the
idea of using Symmetric-key cryptography (and in particular, I would
like to be using Twofish), and then probably encrypting the random
password and IV for each encryption using a public key scheme.
I guess I am wondering what other people's response to such an
approach is, and whether or not there are suggestions for other
approaches. My main concern with the approach noted above is how to
secure the private key used to encrypt the key and IV used to encrypt
the actual text.
I am also wondering if using Twofish is possible with a Rails app.
From what I have seen in the openSSL documentation, only Blowfish -
the predecessor to Twofish - is availble, or AES.
the combination of symmetric and asymmetric encryption as used in
Strongbox works and performs quite well for me. The author of
Strongbox has explained in detail how to do this in his blog (http://
stuff-things.net/2008/02/05/encrypting-lots-of-sensitive-data-with-
ruby-on-rails/). As far as I know, you don't have to encrypt the IV,
just the random password.
In my app, every user has his own pair of keys and the private key is
stored encrypted with the users password. This works fine, as long as
strong passwords are selected. You can make it harder to brute force
the key through password salting and stretching (http://
en.wikipedia.org/wiki/Key_strengthening). When a user is logged in,
his password is sttored temprarily in the session cookie. To prevent
cookie sniffing, you should use encryption for this as well.
Throug this, the encryption and decryption works transparently in the
background without the users even noticing.
Sam, you mentioned that in your app, every user has his own pair of
keys and the private key is stored encrypted with the users password.
How many users does your system have? I was also considering trying
to set something like this up, but I believe it will be far to much
overhead for the number of users my system will have.
As for limiting access to the private key (or password for that
private key), I think that one good step here would be to store it
seperately from both the application server and the database server.
My concern here is that users will be requesting encrypted data fairly
regularly, which means I will need to fetch the encrypted value from
the DB, decrypt it, and provide the plaintext to the user (over an SSL
connection). I am concerned about the type of overhead that
retrieving the key/password from a remote server might be.
Maybe this isn't the right approach for what I need to accomplish. In
more detail, what I want is to allow users to be able to flag certain
content to be encrypted within the DB. The system will have many
users (possibly tens of thousands) that will be able to request to see
this content when they are logged in (which will require the encrypted
content to be retrieved, decrypted, and presented to the user).
Still trying to iron this out. Any more thoughts on the issue?
Sam, you mentioned that in your app, every user has his own pair of
keys and the private key is stored encrypted with the users password.
How many users does your system have? I was also considering trying
to set something like this up, but I believe it will be far to much
overhead for the number of users my system will have.
My system might have potentially many thousand users. For me, this
approach only makes sense, because every user is storing and sharing
very sensitive information, that only a limited number of people may
access.
Maybe this isn't the right approach for what I need to accomplish. In
more detail, what I want is to allow users to be able to flag certain
content to be encrypted within the DB. The system will have many
users (possibly tens of thousands) that will be able to request to see
this content when they are logged in (which will require the encrypted
content to be retrieved, decrypted, and presented to the user).
If all users may access the same information, then you could use a
shared key for all users. You could then encrypt the single private
key with each users password. One drawback with a shared key is, that
if one user has a weak password, it might be very easy to compromise
your data through brute forcing the key. Also it is not so easy to
retract a compromised key. Assigning each user his own pair of keys
gives you other advantages like ensuring Authenticity and Integrity of
the stored information.
Anyway: There is not a single solution, that fits all needs. It all
depends, against what kind of threats you want to protect your data.
And: I am not an encryption expert, just someone trying to solve a
similar problem.