我正在构建一个需要HIPAA合规性的应用程序,为了切入追逐,这意味着我不能允许某些连接在数据库中自由查看(患者及其建议)。
这些表格是通过我的应用中的patients_recommendations
表格连接起来的,该表格运行良好,直到我通过attr_encrypted添加加密。为了减少加密和解密的数量(以及相关的开销),我希望能够简单地加密patient_id
表中的patients_recommendations
。但是,在将数据类型更改为string
并将列名更改为encrypted_patient_id
时,当我尝试重新设置数据库时,应用程序会出现以下错误:
无法写入未知属性`patient_id'
我认为这是因为连接直接寻找列而不是通过模型(有意义,使用模型可能更慢)。有什么方法可以让Rails通过模型(attr_encrypted
添加了必要的辅助方法)?
更新
为了找到解决方法,我尝试将on_save添加到模型中,如下所示:
before_save :encrypt_patient_id
...
private
def encrypt_patient_id
self.encrypted_patient_id = PatientRecommendation.encrypt(:patient_id, self.patient_id)
self.patient_id = nil
end
但这也不起作用,导致unknown attribute
的错误相同。这两种解决方案都适用于我(虽然第一种解决方案可以解决主要问题),是否有任何想法为什么在通过关联创建时不会调用before_save
?
答案 0 :(得分:1)
您应该将PII数据和PHI数据存储在单独的DB中。加密PII数据(包括与提供者或提供者位置的任何关联),然后散列出所有PHI数据以使其更容易。只要两者之间没有直接关联,就不能将PHI数据加密,因为它是匿名的。
答案 1 :(得分:0)
计划A
请勿在{{1}}中将patient_id
设置为nil
,因为它不存在且问题可能会消失。
此外,使用encrypt_patient_id
或nil
结束回调将停止回调链,在方法结尾处放置一个明确的false
。
计划B,重新考虑您的选择
还有更多选择 - 从数据库级透明加密(正式加密磁盘上的数据)到加密文件系统,用于存储某些表空间,以及对列中数据进行加密。
加密连接列听起来像一条不快乐的道路,出于各种原因,从报告问题到加入时的性能问题,这可能非常严重,
你目前遇到的种子问题看起来像是第一次因为这会导致一条糟糕的道路而导致的崩溃(在这种情况下,activerecord似乎很困惑如何处理你的关联,它试图设置{初始化和中断时{1}}。
加密受限数据的开销可能没有您想象的那么高,不确定HIPAA的情况如何,但对于PCI,您并不是完全鼓励在屏幕上呈现受保护的数据,因此加密只会产生很小的开销,因为它相对较少发生(业务需要知道等)。
此外,内存可能被认为是“没有静止而不是在传输中”,理论上你可以在一段有限的时间内缓存一些明确的值,从而节省解密开销。
基本上,加密数据可能不是那么糟糕,加密数据库中的密钥可能比你想象的更糟糕
我建议我们直接谈谈,我正在做PCI DSS合规性的事情,这个话题让我感兴趣。
选项:主键/外键的单向哈希
true
会有patient_id
的哈希值 - 称之为PatientRecommendation
而patient_id
能够从其patient_hash
生成相同的Patient
- 但我建议将patient_hash
存储在两个表中,对于id
,它将是加入的主键,对于patient_hash
,它将是加入的外键,
因此,您可以在这些术语中定义rails关系,并且不再将rails与您的关系方案混淆
Patient
并且结果在加密方面更加健壮且易于数据库处理
如果你坚持不将PatientRecommendation
存储在has_many :patient_recommendations, primary_key: :patient_hash, foreign_key: :patient_hash
中,你可以使用一个普通的SQL语句来做关系 - 不太方便但可行 - 这就是这个伪数据行:
patient_hash
Patient
),因此根据您选择的数据库,这种方法可能非常有效。
然而,即使采取这些措施,使用连接键 也会使您的生活复杂化
稍后我将使用其他选项扩展此帖子