How to secure user data in the database with Rails

2019-02-06 13:04发布

问题:

I am creating a rails application that needs to store a large amount of sensitive data. To assure my customers that the data is being protected, I want to encrypt it on a per-user basis. I have done research looking for gems that can accomplish this. So far I've found strongbox and safe. Together, this would seem to provide a solution for me.

However, I am wondering if this is a common practice. It would seem that most rails applications have some sensitive data to store regarding their users. AuthLogic is handling my password encryption, but emails and other personal data are just as sensitive. Is it common practice to leave these items unencrypted in the database and assume that it will never be compromised? I understand that the database resides in an area that can not communicate with the outside world, but a determined attacker could easily compromise this. Is it common practice for Rails developers leave their data unencrypted and simply trust the security of their web server?

回答1:

The problem with encrypting your database is that anything you encrypt cannot be used in a SQL query, and also, it still has to be decrypted before it can be used. This means that you need to place the decryption key in close proximity to the database, and in most cases, if someone can compromise your database, that means they have also compromised your decryption key at the same time. Thus the encryption step has bought you very little. With passwords, no decryption is necessary because it's actually a hash function. You're far better off making sure the database is never compromised in the first place.

Always assume that if a hacker can compromise any portion of your security, they can compromise all of it. Chain is only as strong as its weakest link and all that.

Credit card numbers and social security numbers (which fortunately you don't usually need to index on) are probably the most obvious exception to this, but if you have to ask this question, you've got no business storing those items in the first place. There's all kinds of legal trouble you can get into for messing that stuff up.



回答2:

Credit card number, SSNs, etc should always be stored encrypted.

Passwords should always be stored encrypted, using a one-way hash. This means that when the user supplies a password, you can determine if it matches what you stored in the DB, but given only the encrypted representation in the DB, you cannot from that determine their password, short of brute force/dictionary attacks.

I find that in my app's, I like to add unencrypted_**** readers and writers to my class, to make dealing with the encrypted representation painless.

class User
  # has db column encrypted_cc_number
  def unencrypted_cc_number
    WhateverEncryptionClassYouUse.decrypt(encrypted_cc_number)
  end
  def unencrypted_cc_number=(val)
    self.encrypted_cc_number = WhateverEncryptionClassYouUse.encrypt(val)
  end
end


回答3:

Using layered security mechanisms and strong cryptography is good practice if you are storing a large amount of sensitive data. It is required by the Payment Card Industry’s Data Security Standard (PCI DSS). I suggest that you read the following guideline document: https://www.pcisecuritystandards.org/pdfs/pci_fs_data_storage.pdf.

You should definitely not "assume that it will never be compromised"