求大佬们给一个加密存储的思路

2021-05-28 00:40:10 +08:00
 Baymaxyu

场景:

需求:

  1. 实现 web 系统中每个用户都有自己的密钥来解密获得数据(就是用户自己输密钥,前端解密);
  2. 每个算法分析程序对加密数据也要用自己的密钥来解;
  3. 对所有需要加密的字段进行加密存储(目前都是明文的);
  4. 可以更换用户的密钥不影响加密数据;

目前遇到的问题:

  1. 不同语言的加密算法能否通用?
  2. 导师是想用一个统一的 api 来实现,让所有对数据库的请求过这个加解密服务(未来还要加上一些访问控制),但是目前的程序 php/java 都是用其自带的 orm 来实现 mysql 操作的(修改工作量很大);
  3. web 系统存在一些十分复杂的 sql 查询,怎么能方便的转化成 api 的形式;

目前的设想:

  1. 使用统一的对称加密密钥( key )加密数据(可能每个表一个密钥),这个密钥用加密服务的一个密钥加密( sys-key )存储;
  2. 程序请求数据的时候要先验证程序身份( username+pwd ),然后用其对应的公钥加密( key,经过 sys-key 解密后),然后和数据一起发回去,由程序根据自己的私钥解密。

但是可能存在问题 1 (不同编程语言加密算法是否通用?),还有就是该怎么设计这个 api 才能满足系统中各类程序的需求 因为导师又想监控管理所有的请求(做访问控制),只能来一个新的需求就再新增一个 api ?(先不管性能,就是一个辣鸡项目,只是想快捷做完应付老师)

2100 次点击
所在节点    程序员
10 条回复
eason1874
2021-05-28 01:28:58 +08:00
1 、被广泛认可的加密算法在不同语言都有实现,是通用的,只是某些默认值会不一样,别用默认值就行。

2 、MySQL InnoDB 支持表空间加密,采用 AES,需要安装插件,是自动的,用户提供 master key 去加解密 tablespace key 就可以,不用改其他代码。这是无感知的,只是防拖库。

3 、允不允许用户提交 SQL 自定义查询这个见仁见智吧,这在 V2EX 也差不多是月经问题了,有支持的,有反对的。反正我不会允许,顶多包装几个查询参数丰富的接口。

用户加密,不怕性能问题就用非对称加密,方便甩锅。让用户把公钥提交过来加入白名单,用它加密返回结果。
jim9606
2021-05-28 01:29:11 +08:00
感觉你只需要在数据库或者后端服务搞 ACL 访问控制啊。数据库提供两个账户给后端服务用,其中一个可以访问敏感数据。

如果你这里的两个系统都是受信任环境下的(就是外人获取不到程序,运行在自己控制的服务器上),web 应用自己做 ACL 就行。如果不是(也就是需要直接对外暴露 mysql 端口),那你可能得用 mysql 中间件做复杂的 SQL 过滤了。

后端 per-user 加密--前端 per-user 解密 这个流程很多余,前端始终是获得解密的数据的。如果只是想避免连接窃听的话上 TLS/HTTPS 就行了,
3dwelcome
2021-05-28 01:29:44 +08:00
是我的话,就写个中间代理层,你如果修改现在的代码,难免会引入新的 BUG,很麻烦的。

mysql 全局加密 -> 中间层解密 -> java 正常用 api 获取数据 -> 依赖 SSL 安全性把数据给前端 -> 前端用密码来授权访问。

你第四点需求,"可以更换用户的密钥不影响加密数据", 想密钥变,但数据不变,那也只能用权限控制了。

导师的首要需求就是数据库的数据加密,别的都可以忽悠。所谓前端加密,你让导师上 V2 问问,保证一大片都说不靠谱。
whileFalse
2021-05-28 06:54:33 +08:00
我理解,每个算法分析程序应该具备独立于其他算法的密钥,此密钥不依赖于特定用户,且可以解密所有用户的数据。


0. 为每个算法分析程序创建独立的密钥,可以是非对称加密,称为该算法的主密钥。应安全地保存该算法主密钥。考虑使用独立的数据库,并合理设置权限。
每个算法分析程序还可以设置自己的加密上下文字符串。这可以一部分保存在程序代码中,另一部分在运行时以环境变量等参数提供。该字符串参与加密。这可以保证仅攻破数据库也不能直接拿到主密钥。

1. 每个用户在注册时随机创建一个对称加密密钥,称为该用户的数据密钥。该密钥用于加密该用户的数据,并且不得将该密钥明文写入数据库。

2. 使用每个算法主密钥加密用户的数据密钥,将加密结果写入数据库中各个算法独立的表中。

3. 使用每个用户在注册时指定的密码或密码的哈希加密该用户的数据密钥,并将经用户密码加密过的数据密钥写入数据库。注意此加密数据密钥不应用于验证用户登录。用户每次更改密码,应更新此加密数据密钥。

4. 用户登录后,将用户密码加密过的数据密钥传输至用户前端。
huang119412
2021-05-28 08:46:45 +08:00
重要的事情再说一遍,千万别自己设计加密算法。
Baymaxyu
2021-05-28 09:03:56 +08:00
@jim9606 感谢感谢,让前端解密纯粹就是为了安全(导师说怕别人偷了用户的账号和密码,多一层密码输入多一层保障)这 web 应用只有个位数人用不用考虑性能
Baymaxyu
2021-05-28 09:04:46 +08:00
@eason1874 感谢感谢大佬,确实老师只是想要数据安全
Baymaxyu
2021-05-28 09:13:51 +08:00
@whileFalse 感谢老哥,不过我的场景中用户不产生数据(仅查询、修改、删除数据),主要是其他程序产生数据,还有一部分数据是人工放进去了(导师说这些都是珍贵的财产需要保护起来)
rationa1cuzz
2021-05-28 11:41:01 +08:00
是我的话数据库数据加密,其他事情 api 来做
用户获取数据需要登陆外加权限验证获取一个有过期时间或者使用次数的 加密 key(身份认证)
每次请求数据需要带上这个加密 key 通过 api 进行验证(身份认证),通过后再去取数据解密传给前端,中间加 https
前端要加密的话只能想到,每次后端拿到数据进行次加密并将密钥给前端(数据二次加密),前端解密展示
Baymaxyu
2021-05-28 14:27:26 +08:00
@rationa1cuzz 感谢大佬的思路

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/779688

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX