V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
cppc
V2EX  ›  信息安全

如何保护配置文件中的敏感信息,比如数据库密码

  •  
  •   cppc · 118 天前 · 5433 次点击
    这是一个创建于 118 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我们产品部署在甲方数据中心,同事(以下简称 A,算是项目经理)反馈甲方要求不得保存明文敏感信息:

    • 各种密码、密钥都是敏感信息
    • 存储位置包含磁盘文件、数据库

    我提出方案有

    1. 数据加密: 配置文件中的敏感信息加密保存,解密密钥保存在配置文件中。A 的意见:加密密钥也属于密码、密钥。
    2. 用管分离: 使用密码库,配置中心之类的基础设施,我们拉取配置信息。A 的意见: 连接配置中心需要用户名 /口令,也是密码;配置中心连数据库需要数据密码,也是密码。

    我不确定是 A 自己没有理解需求,还是甲方确实这么提出,这不就无限套娃么。

    我们的客户是金融行业,请问这方面有无具体的技术规范?如果我的方案可行,要怎么样才具有说服力呢?

    PS: A 坚持认为自己已经跟甲方沟通好了,不愿意再去询问具体要求

    第 1 条附言  ·  118 天前

    感谢大家捧场,补充一下: 1 保护的是服务端配置文件中的敏感信息,配置文件在磁盘上或者数据库中,其他业务数据就先不讨论了 2 只要是我方用到的配置文件都需要解决,不管它是业务服务还是中间件(因为这个原因redis都不能用了,影响极大) 3 目前能让A满意的方案就是用UKey之类的硬件,这是A自己提出方案,我不太赞成,因为这玩意侵入性很强,而且还得有一套系统去管理ukey 4 感觉对哪些属于敏感信息的定性很重要,可我又拿不出说服力的东西

    76 条回复    2022-04-22 08:07:16 +08:00
    xuanbg
        1
    xuanbg  
       118 天前
    密码做个 md5 差不多了,最多加点盐,可以避免和别人家被拖的库碰撞。别的如身份证号、手机号什么的,可以加密啊。至于密钥的管理么,你让他买硬件的密码机。这样只要密码机不被搬走,就不用担心泄密了。
    LxnChan
        2
    LxnChan  
       118 天前
    用非对称式加密呢?或者用硬件 /生物识别解密工具(智能卡 /指纹等)?
    sjzjams
        3
    sjzjams  
       118 天前
    AWS Key Management Service (KMS)
    orcinus
        4
    orcinus  
       118 天前
    解密密钥直接写代码里?
    Jinnyu
        5
    Jinnyu  
       118 天前   ❤️ 1
    提供个思路
    写一个配置服务端和客户端 SDK
    服务端从数据库里读取配置信息(密码加密)
    客户端在启动时生成一个一次性的 RSA 密匙对, 随请求将公匙发送到服务端,
    服务端通过公匙对配置进行加密 (可选整个配置加密或部分加密)
    然后客户端接收到响应后通过私匙进行解密
    这样可以保证客户端信息都是安全的
    hhjswf
        6
    hhjswf  
       118 天前
    @Jinnyu 你这也不符合甲方需求,绕来绕去人家还不一定听得懂
    hhjswf
        7
    hhjswf  
       118 天前
    A 是产品吗?甲方要个月亮是不是也得给他摘呀。需求评审不通过砍了,太离谱了
    cppc
        8
    cppc  
    OP
       118 天前 via iPhone
    @Jinnyu 配置服务器也需要读配置文件,它也得解决自己的配置文件的安全问题,不过你提供思路解决了配置服务器和客户端交换信息的问题,我觉得解决了部分问题
    3dwelcome
        9
    3dwelcome  
       118 天前
    要不考虑用 login session 吧,为每个用户分配一个 session 登录,就和银行的实时 U 盾差不多,会过期。

    密码最大的问题,就是不会过期。同时也没身份鉴别功能,一旦泄露后,谁用这个密码登录的,你都不清楚,不好追责。
    cppc
        10
    cppc  
    OP
       118 天前 via iPhone
    @hhjswf 说实话,我就觉得离谱,我跟他说这种甲方的项目经理其实不懂这些技术,得我们自己去输出技术方案,才能占据主动,但是他比较闷骚,不愿意去沟通
    wolfie
        11
    wolfie  
       118 天前
    甲方数据中心 不就属于生产环境吗。
    启动脚本覆盖参数啊。
    des
        12
    des  
       118 天前 via iPhone
    要不试试用证书验证?或者智能卡?
    IceBay
        13
    IceBay  
       118 天前
    开个玩笑,把密码分割,交由不同人保存不同部分。
    Jinnyu
        14
    Jinnyu  
       118 天前
    @hhjswf #6 我明白, 因为当时我这也是这样要求的,
    解决方案是我在代码中写了部分规则, 每天按照一定的规则去生成密匙
    angryfish
        15
    angryfish  
       118 天前   ❤️ 3
    不设置密码就不需要保存密码了,逃!
    Jinnyu
        16
    Jinnyu  
       118 天前
    @hhjswf #6 而且这个问题本来就是鸡生蛋 蛋生鸡
    Vieufoux
        17
    Vieufoux  
       118 天前
    Vault
    ysc3839
        18
    ysc3839  
       118 天前
    这要求就是想要外部解密吧?那你的方案都不可行。最简单的是弄成启动时要求输入密码,然后密码保存在内存中。更安全的话用智能卡,每次解密都去请求智能卡。
    swulling
        19
    swulling  
       118 天前
    这个其实很简单,比如你的配置文件是
    EncryptCredentials=xxxx 或者 EncryptPassword=xxxx

    代码里写死解密的密码是 123 ,然后解密后拿到密码 /密钥就行

    国内很多金融都是这样的,配置文件里不能放明文的密码,需要根据代码里的解密密码解密一下。这种项目做多了就知道套路了。

    很多公司还要求这个 Encrypt 方法是国密 SM4
    swulling
        20
    swulling  
       118 天前
    从安全的角度看就是脱裤子放屁,但是人家就有这个要求~

    做了好多这种项目了,都是一些银行和金融机构。
    pckillers
        21
    pckillers  
       118 天前
    把有线网卡 MAC 设置为数据库账号的密码,写死进代码。这样就没有密码了。这是硬件加密!必须这台服务器才能访问!
    libook
        22
    libook  
       118 天前   ❤️ 1
    如果描述不清需求,让 A 提一个草案,根据草案来理解需求。

    文件、数据库里的敏感信息可以加盐加密,秘钥放在配置文件里,配置文件分成敏感配置文件和非敏感配置文件,非系统管理员禁止接触到敏感配置文件,这样确保仅当程序部署在正式服务器上的时候才能读到敏感配置文件。

    不同环境的敏感配置信息不同,比如数据库秘钥在开发、测试、正式环境用三套不一样的。

    用 K8s 的话可以利用 K8s 自带的 Secret 机制,在 pod 部署的时候才挂载上敏感配置文件。

    想方便一点的话可以用配置中心,可以更细粒度地划分权限,配置中心配置 IP 白名单,仅受到信任的服务器可以访问,这样即便开发人员接触到配置中心的 Access Key 也不会有问题。

    其实上面说了这么多核心思路就是把敏感配置信息和代码分离。

    防范系统管理员基本是不可能的,因为跟服务器没有物理隔离(可以直接操作服务器),顶多加堡垒机和三权分立来制约一下。

    安全都是相对的,没有绝对的安全,只有防范特定问题的安全,所以也可以问一下需要防范哪些问题,看是不是一个 X/Y 问题。
    angryfish
        23
    angryfish  
       118 天前
    加密狗吧,狗在密码在,狗不在密码不在
    tomczhen
        24
    tomczhen  
       118 天前 via Android   ❤️ 1
    如果一开始假定运行环境就是不可信的,软件方案再怎么纠结也没用。非要抬杠,建议上 TMP 模块解决。
    hhjswf
        25
    hhjswf  
       118 天前
    @swulling 你就没看懂 op 说的,连密文都不能有
    swulling
        26
    swulling  
       118 天前
    @hhjswf 我相信我看懂了,而且也做过好多类似的需求。

    「 A 的意见是说解密密钥保存在配置文件中」这个只需要把解密密钥写死在代码里就行了。
    swulling
        27
    swulling  
       118 天前
    就是这个方案的修改:

    > 数据加密: 配置文件中的敏感信息加密保存,解密密钥保存在配置文件中。A 的意见:加密密钥也属于密码、密钥。

    数据加密: 配置文件中的敏感信息加密保存,解密密钥写死到代码里。
    liuzhaowei55
        28
    liuzhaowei55  
       118 天前 via iPhone
    一般来说研发不掌握线上生产权限,而运维拥有线上权限,所以通过启动命令注入环境变量,程序读取,是比较通用的交互方式
    swulling
        29
    swulling  
       118 天前   ❤️ 9
    不要用安全的角度理解客户的需求,而是要满足客户的内部规章制度。

    - toB 安全的第一要义。


    举几个安全漏洞修复的实际例子:

    - 客户内部安全扫描出 Nginx 漏洞,是因为 nginx 会输出版本号,老版本有 CVE 。解决办法并不是升级 nginx ,而是让 nginx 不要输出版本号或者输出高版本的伪造的版本号。
    - 客户内部安全扫描出 MySQL 弱密码,解决办法也不是更换 MySQL 密码,而是直接设置访问 IP 白名单,不让扫描机器扫到这个 MySQL 。


    太多太多了,不做这行不了解这些套路。
    alvinbone88
        30
    alvinbone88  
       118 天前   ❤️ 1
    金融行业应该有硬件加密方案,问问就行了
    cppc
        31
    cppc  
    OP
       118 天前 via iPhone
    @swulling 哎,这个我当时就想到了,A 担心甲方询问处理细节,到时候不好回答,也就是说他内心是不认可这种方案的
    cppc
        32
    cppc  
    OP
       118 天前 via iPhone
    @wolfie 我方服务需要自动启动,启动脚本里面不能写密码之类
    swulling
        33
    swulling  
       118 天前
    @cppc 大家都是这么做的,你就放心搞吧,总比没有方案强。
    duduaba
        34
    duduaba  
       118 天前
    密码加密后直接写在代码里,说不定这种骚操作还是最终的方案。
    37Y37
        35
    37Y37  
       118 天前 via Android
    sparky
        36
    sparky  
       118 天前
    没有绝对的安全,只能不断提高破解的成本
    janus77
        37
    janus77  
       118 天前
    用配置中心,然后配置中心只开放少数几个账户,用硬件加密。甲方自己内部要看也必须通过硬件。硬件给他们的技术部门自己拿着,后面有锅就可以自然甩出去了
    cppc
        38
    cppc  
    OP
       118 天前
    @janus77 我们之前做过的方案跟这个有相似之处,解密密钥在硬件中,只能写入不能读取,可以调用硬件在设备内部执行解密算法,这样,最外层的密钥在设备中,设备由甲方运维持有,也就丢掉了这个烫手的东西。

    我纠结的就是我附言 1 里面提到的,这个方案侵入性太强,所有应用都需要置入操作硬件的 SDK ,修改服务的启动逻辑。要命的是,我们用到的开源中间件也得去改造,一旦改造,性质就变了,公司得负责到底。


    我希望的方案和 @libook 相似
    1. 要对信息进行区分,敏感信息也要分重要程度
    2. 根据 [JR/T 0071—2012] ,安全分为物理层、网络层、主机层、应用层等,那么在特定外部安全环境下,一些不那么重要的敏感信息,可以存储明文。问题在于我不是权威,我的理解算个 P ,苦于没有可参照的成功案例,没有具体的权威规范。
    PHPer233
        39
    PHPer233  
       118 天前 via Android
    用 AES 算法对密码加密,将密文保存在配置文件中。解密的密钥通过 jvm 启动参数传递给程序。
    bxb100
        40
    bxb100  
       118 天前
    @Vieufoux Valut +1
    ysc3839
        41
    ysc3839  
       118 天前 via Android   ❤️ 1
    @cppc 硬件加解密有标准接口的,比如 OpenPGP Card 或者 PIV Card ,大多数操作系统都内置驱动程序,没想象中那么麻烦,甚至可以弄成全盘加密 https://wiki.ubuntu.com/SmartCardLUKSDiskEncryption
    要负责到底也很合理,因为是甲方提的需求。如果预算不足的话还是别在技术问题上纠结了。
    janus77
        42
    janus77  
       118 天前   ❤️ 1
    @cppc #38 用技术角度没法解释,在甲方眼里你说的那些重要程度分级,一律视为安全风险,所遵守的标准是一样的。这个标准也就是甲方提出的无限套娃,这种无解的,不要太期望保持易用性。。。
    masterclock
        43
    masterclock  
       118 天前
    HashiCorp Vault 类的不就行了?常规操作啊
    cppc
        44
    cppc  
    OP
       118 天前
    @PHPer233 这个不行,一来程序要无人启动,再就是命令行参数是可以通过进程管理器看到的(至少 windows 系统是这样),等同于明文。
    cppc
        45
    cppc  
    OP
       118 天前
    @masterclock 调研过,不能直接用,前面我解释过了。这些东西我是很愿意使用,但是在国内一些行业里面,国外的东西就是"水土不服",无奈。
    wizardyhnr
        46
    wizardyhnr  
       118 天前
    非对称加密+硬件 key 确实可控性更高,从客户角度来说,威胁模型就是服务器破解,文件都被 copy 走,如果在一台机器上同时保存加密数据和密钥确实属于脱裤子放屁,肯定还是要实行隔离才有保护力。
    就像之前那个 Bvp47 ,如果不是他们的密钥被偷出来了,别人也分析不出来什么。
    zlowly
        47
    zlowly  
       118 天前
    Valut +1
    dingwen07
        48
    dingwen07  
       118 天前
    上 Hardware Secure Module
    lanlanye
        49
    lanlanye  
       118 天前
    上次处理这种需求是配置用 SM4 加密的,密钥直接写死在代码里,给客户部署时的容器里只有一个二进制文件。
    c6h6benzene
        50
    c6h6benzene  
       118 天前
    之前做后端是的时候有接触 HashiCorp Vault (还有其他类似的 Vault ),密码和配置都可以存在 Vault 里面,程序端只用通过某些验证方式( Role/ID 之类)去取就好,明文写出来的就只有变量名。

    如果用 Springboot 的话还有 Spring Cloud Vault 来提供支持: https://cloud.spring.io/spring-cloud-vault/reference/html/
    OldCarMan
        51
    OldCarMan  
       118 天前 via Android
    可不可以这样子,偷换一个概念,全部必须设定的密码采用各种文件的 MD5 值来代替。
    HertzHz
        52
    HertzHz  
       117 天前
    TPM 或者硬件安全模块
    GeruzoniAnsasu
        53
    GeruzoniAnsasu  
       117 天前   ❤️ 1
    > PS: A 坚持认为自己已经跟甲方沟通好了,不愿意再去询问具体要求

    低级产品经理是这样的。toB 产品千万不要「做客户要求的东西」,得「用你想做的东西满足客户期望」。2b 其实是个卖方市场,很多很多方案都是各家临场想出来的,没有人真的做出来了客户要的那个东西,自己的故事编得更完善而已。


    落到方案,最本质的一点你们 A 根本没想到,即,这个需求的目的是 合规 还是 真的安全建设。这是 2b 安全行业最重要的信息。

    如果为了合规,你就让 A 去抠规范,把规范描述的情况全绕开,这个方案就是完美的
    如果为了安全,你就让 A 告诉客户你比他们懂,让销售推动一场技术选型的评审,然后 A 来出评审方案,只要自家方案能打赢友商,这个方案就是完美的。


    最后才是实现上的事:
    需求没说密钥不能存在内存中对吧,加密过程密钥全程不落地不就合乎需求了吗?
    说白了真的根本不是用什么技术的问题
    abc612008
        54
    abc612008  
       117 天前
    楼上那些投机取巧和掩耳盗铃的,我希望以后不会用到你们做的产品。
    defunct9
        55
    defunct9  
       117 天前
    RickyC
        56
    RickyC  
       117 天前
    确实挺难的;
    要么就用密钥:保护好密钥;
    要么就用密码。
    ------
    但是都难以做到绝对安全。
    ------
    更安全的方法只有:策略。
    比如经常更换密码和密钥等。
    ------
    所谓的安全,只不过是比想要破解你的人跑得快。
    而不是绝对不可破解。
    sampeng
        57
    sampeng  
       117 天前   ❤️ 1
    我碰到过。。。以前在华为就是这个要求。。
    为了这个我还跑去改了 mysql 源码。因为 mysql 的密钥会明文存储在本地的一个目录(华为安全部门全盘搜索 mysql 密码我也是醉了)。

    你应该反问,这台机器总要有人上来维护吧?密码还是密钥?

    是不希望进服务器的人有数据库的密码?都进到服务器了。。什么事干不了?

    绝对安全?没有。。我唯一做的最复杂的安全方式是密码在编译时就用三种不同的方法加密。每次用的时候解密。除非破解二进制,搞明白我是怎么加密解密的。这个密码是不可能拿到的。
    aboat365
        58
    aboat365  
       117 天前   ❤️ 1
    首先声明没有绝对的安全!不清楚楼主家的产品是否是 JAVA 程序,如果是,一般用 jasypt 即可。
    分析一下楼主的需求,就是登录部署服务器,不能看到程序配置文件中的各种密码,但程序运行是需要密码去连接其它服务。那么,程序运行时服务器内存中一定有明文密码,连接数据库服务的网络中也有密码。
    基于以上分析,针对楼主的问题纯软解决办法就是程序启动时,输入启动命令带上一个解密密码参数即可。这样就可以保证服务器上永久存储介质上不保留任何明文密码。缺点就是程序每次启动需要人工输入密码。

    如果上硬件,比如 U 盾,看具体方案和场景了。最后补充说明,系统安全是只木桶,取决于最短的那块板。
    crayygy
        59
    crayygy  
       117 天前
    不知道 USB Key 可不可行
    youyoumarco
        60
    youyoumarco  
       117 天前
    以前也碰到过一些公司有这个要求,但是那时候就是说密码机这种,然后他们一听钱上来了,就放弃了
    tonzeng
        61
    tonzeng  
       117 天前
    UKey 不是銀監會要求的嗎。。。
    kcross
        62
    kcross  
       117 天前
    还不如做好权限管理 敏感操作做验证
    OldCarMan
        63
    OldCarMan  
       117 天前
    哈哈,看到你这问题和这几天发生的事情,突然想到一个有点不相关的事情,北方某大国或者西方某大国,关键时候都是某种密码箱随身带,这是不是侧面说明了,想完全去密码很难,不断的加密和解密,个人觉得某种意义上只是套娃,相对于这些,提供一个尽量安全的生产环境和严格的 IT 管理举措才是重点。(纯属联想和个人拙见,逃🐶)
    RickyC
        64
    RickyC  
       117 天前
    @xuanbg 密码本身就不安全;你能保证使用者自己不泄露吗?
    mpi2018
        65
    mpi2018  
       117 天前
    客户金融行业,这种需求就是为了合规,密钥写死在代码里就行了
    wsgfz000
        66
    wsgfz000  
       117 天前
    之前线上环境我是写到对应机器的环境变量里的,写代码里因为 git 每个本地也会存代码,还是有比较大的风险。

    放线上机器(内网,无公网 IP )里,假设的是如果他都 hack 进内网的机器了,那他啥事干不了?
    zhujq
        67
    zhujq  
       117 天前
    @swulling 大哥过来人,我们之前也是这样搞的😄
    Jooooooooo
        68
    Jooooooooo  
       117 天前
    搜 kms
    SSang
        69
    SSang  
       117 天前   ❤️ 1
    用环境变量传呗(用 export ),只有部署时候需要用到,启动时候读完就写进内存,然后环境变量就失效了,但要是挂了就还得再手动部署
    tabris17
        70
    tabris17  
       117 天前
    存环境变量
    SSang
        71
    SSang  
       117 天前
    而且我有个问题,楼上说的,解密密钥写代码,配置文件存密文,这不是一样没用吗
    我好像不需要知道你怎么解密的,我只要知道密文然后传给你就好了
    这不是和加盐,做 md5 、哈希什么的一样吗
    可靠的加密应该只能是非对称加密吧,但这要求必须有权威认证机构
    SSang
        72
    SSang  
       117 天前
    其实写死在环境变量也行,只要客户不知道怎么查环境变量,你就说,看文件里面没有,忽悠他就好了
    CapNemo
        73
    CapNemo  
       117 天前
    kenvix
        74
    kenvix  
       117 天前
    这个需求就适合用 TPM 啊
    dotw2x
        75
    dotw2x  
       89 天前
    Azure Key Vault 之类的服务好像比较适合这种场景,支持使用软件密钥加密,也支持 HSM 。
    aaniao002
        76
    aaniao002  
       65 天前 via Android
    给你个建议,并不要纠结有没有意义,因为我甲也纠结了好久,规定就是这样的,你找个谁都别说的双向加解密算法,只要存密码文件是独立的,打开是没有明文密码的,加密算法是别人看不懂的就行。
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   967 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 20:16 · PVG 04:16 · LAX 13:16 · JFK 16:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.