首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails 4加密外键

Rails 4加密外键
EN

Stack Overflow用户
提问于 2014-01-21 02:13:26
回答 2查看 1.1K关注 0票数 2

我正在构建一个要求HIPAA遵从性的应用程序,这意味着我不能允许某些连接在数据库中自由查看(病人和他们的建议)。

这些表是通过我的应用程序中的patients_recommendations表连接的,在我通过加密添加加密之前,这个表工作得很好。为了减少加密和解密的数量(以及相关的开销),我希望能够简单地加密patients_recommendations表中的patients_recommendations。但是,如果将数据类型更改为string,将列名更改为encrypted_patient_id,则当我试图重新启动数据库时,应用程序会出现以下错误:

无法写入未知属性`patient_id‘

我认为这是因为join直接查找列,而不是通过遍历模型(有道理,使用模型可能要慢一些)。有什么方法可以让Rails通过模型( attr_encrypted已经添加了必要的助手方法)?

更新:

为了找到解决方案,我尝试在模型中添加一个before_save,如下所示:

代码语言:javascript
复制
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时,有什么想法没有被调用呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-23 20:09:33

您可能应该将PII数据和PHI数据存储在单独的DB中。加密PII数据(包括与提供者或提供者位置的任何关联),然后计算出所有的PHI数据,使其更容易。只要两者之间没有直接关联,就可以接受不对PHI数据进行匿名加密。

票数 1
EN

Stack Overflow用户

发布于 2014-01-23 07:09:48

计划A

不要将patient_id设置为nil in encrypt_patient_id,因为它不存在,并且问题可能会消失。

另外,以nilfalse结尾的回调将停止回调链,并在方法的末尾放置一个外植体true

计划B,重新考虑你的选择

还有更多的选项--从数据库级透明加密(它对磁盘上的数据进行正式加密),到用于存储特定表空间的加密文件系统,到对列中数据的完全加密。

加密联接列听起来像是一条通往不幸的道路,原因多种多样,从报告问题到加入时的性能问题都是必要的,这可能是非常严重的,

您目前在这个种子上遇到的麻烦看起来就像它在这条可能是一条不好的道路上引起的第一次颠簸(在这种情况下,activerecord似乎对如何处理您的关联感到困惑,它试图在初始化和中断时设置patient_id )。

加密受限数据的开销可能不像您想象的那么高,不确定HIPAA的情况如何,但对于PCI,则不完全鼓励您在屏幕上呈现受保护的数据,因此加密只会带来很小的开销,因为这种开销相对较少(业务需要知道等)。

此外,内存可能被认为是“不休息,也不是在传输中”,理论上您可以在有限的时间内缓存一些明确的值,从而节省解密开销。

基本上,加密数据可能没有那么糟糕,而数据库中的密钥加密可能比您认为的更糟。

我建议我们直接谈谈,我正在做PCI的合规工作,这个话题让我很感兴趣。

选项:主/外键的1路散列

PatientRecommendation将有patient_id的散列--称为patient_hashPatient将能够从其id中生成相同的patient_hash --但我建议将patient_hash存储在两个表中,对于Patient,它将是连接的主键,对于PatientRecommendation,它将是连接的外键,

因此,您可以使用这些术语定义rails关系,并且rails将不再混淆您的关系方案。

代码语言:javascript
复制
has_many :patient_recommendations, primary_key: :patient_hash, foreign_key: :patient_hash

其结果在密码学上更健壮,便于数据库处理。

如果您坚持不将patient_hash存储在Patient中,您可以使用普通的SQL语句来执行这种关系--这种关系不太方便,但却是可行的--在这个伪SQL的行中这样做:

JOIN ON generate_hash(patient.id) = patient_recommendations.patient_hash

例如,Oracle有一个创建函数索引的选项(比如create index generate_hash(patient.id)),因此根据您对数据库的选择,这种方法可能非常有效。

然而,玩连接键会使你的生活变得很复杂,即使使用这些方法。

稍后,我将在这篇文章中进一步介绍其他选项

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21247876

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档