V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
renfei
V2EX  ›  问与答

登录接口是应该自定义加密还是依靠 HTTPS 就行?

  •  1
     
  •   renfei · 2023-07-14 17:07:26 +08:00 · 2686 次点击
    这是一个创建于 444 天前的主题,其中的信息可能已经有所发展或是发生改变。
    各位大佬,每次安全测评的时候,总说我登录明文传输,自己写一套加密逻辑前后端都不太愿意用,因为还涉及到非对称加密、交换对称秘钥,大家都不想这么麻烦,每次我都应答用 HTTPS 来保护明文传输的问题

    那么,按正常场景来说,是应该自己弄一套加密呢,还是套 HTTPS 万事大吉呢?
    33 条回复    2023-07-17 11:48:00 +08:00
    tool2d
        1
    tool2d  
       2023-07-14 17:16:33 +08:00
    你要确保客户端用了 SSL Pinning 技术,那流量就是相对安全的,不加问题也不大。

    如果黑客能破解你的 SSL Pinning ,那他大概率也能破解你的非对称加密。
    ysc3839
        2
    ysc3839  
       2023-07-14 17:18:41 +08:00 via Android
    个人建议客户端提交前用 md5 或 sha1 等弱 hash 函数取密码的 hash 值再提交,后端用 argon2 等强 hash 进行验证。

    一定要弄一套加密的话,参考 B 站登录接口的方案(现在如何不知道,以前是这样的),先请求一个接口获取 RSA 公钥,登录请求的 post 数据全都用这个公钥加密,后端用私钥解密后再处理。
    javalaw2010
        3
    javalaw2010  
       2023-07-14 17:20:18 +08:00
    我是赞同只依靠 https 的,但如果有同事反对,我会懒得解释(实际上我可能会简单解释一下以表示我不是个不顾安全的憨批),然后上一套简单的对称加密完事儿。
    CloudMx
        4
    CloudMx  
       2023-07-14 17:23:05 +08:00
    这个是两个维度的:
    1 、HTTPS 强制要求是应对中间人的
    2 、业务敏感字段数据要求有一些是规范政策相关的,技术上的话比如:一些留存 web 日志,相对明文是可以提升攻击者成本的。
    mozhizhu
        5
    mozhizhu  
       2023-07-14 17:25:16 +08:00
    我干掉了账号密码,主导让微信扫码登录,然后被埋怨了;但是依旧推下去了,因为他们的 123456 太粗暴了
    tianmalj0613
        6
    tianmalj0613  
       2023-07-14 17:41:32 +08:00
    @ysc3839 #2 现在百度好像也是这样的
    Worldispow
        7
    Worldispow  
       2023-07-14 17:56:24 +08:00
    自定义加密和 https 加密是两个事吧,https 是公共链路加密。
    自定义加密是内部网络加密,比如前后端交互、公司内部不同系统间交互等等。
    renfei
        8
    renfei  
    OP
       2023-07-14 18:02:50 +08:00
    @Worldispow #7
    在我看来似乎是一个事儿

    https 是把整个请求体加密了,多个 CA 中间认证

    自定义加密,我也是模仿 https 先通过非对称加密交换一个秘钥,后续通过秘钥对称加密,只不过加密的是我指定的字段而不是整个请求体,并且没有 CA 认证
    MigrantWorkers
        9
    MigrantWorkers  
       2023-07-14 18:51:56 +08:00
    目前我们的方案 jwt+sig ,用了几年了 没啥问题。也可能是体量小
    cozof
        10
    cozof  
       2023-07-14 18:53:00 +08:00 via iPhone
    用非对称,把公钥给前端,前端加完密数据发回。不行?
    lovelylain
        11
    lovelylain  
       2023-07-14 18:57:20 +08:00 via Android
    @ysc3839 先 hash 再提交意义不大,不加可过期的盐,hash 值相当于密码,加动态盐,后台要存储密码明文才能验密,还是 RSA 公钥加密吧,安全不复杂
    yzkcy
        12
    yzkcy  
       2023-07-14 19:03:10 +08:00
    针对明文传输整改的话,HTTPS 和前端加密都要上。
    yinmin
        13
    yinmin  
       2023-07-14 19:07:30 +08:00 via iPhone
    @renfei 和同事沟通这类问题,如果说哪种技术好,是没法说服对方的。

    最简单的方式是:参考大厂的 api 加密模式,例如你对标微信接口的加密方式,然后和领导、同事建议我们采用微信接口一样的加密模式,如果对方不同意,你让对方说他们的方案有啥好?为什么微信(再举例类似几个大厂接口)不采用?你们的技术方案比微信团队强?
    ysc3839
        14
    ysc3839  
       2023-07-14 19:15:39 +08:00 via Android
    @lovelylain 先 hash 再提交是为了尽可能避免用户隐私泄漏,印象中等保要求不能提交原始密码
    kaneg
        15
    kaneg  
       2023-07-14 19:26:42 +08:00 via iPhone
    https 完全可以啊,安全方面最好不要自己造轮子,要用业界标准协议,否则可能适得其反。
    chenjia404
        16
    chenjia404  
       2023-07-14 19:39:30 +08:00
    我之前做过一个方案:
    哈希(用户名+密码+网站名)发送给服务器,服务器拿到提交的哈希和用户名,再哈希(用户名+密码+网站名+盐),把最后一步的哈希存在一张哈希表里面,下次用户登录的时候,只需要验证哈希表中是否有元素即可。
    leonshaw
        17
    leonshaw  
       2023-07-14 20:03:50 +08:00 via Android
    一般明文就可,但是后端看到明文,对习惯用同一个密码的用户会有问题。可以考虑用 KDF 处理一下
    renfei
        18
    renfei  
    OP
       2023-07-14 20:15:09 +08:00
    @MigrantWorkers #9 获取 JWT 的时候呢,是不需要传输用户名、密码,我想问的是传输密码时的加密,还没到拥有 JWT 的阶段呢
    renfei
        19
    renfei  
    OP
       2023-07-14 20:16:36 +08:00
    @cozof #10 非对称加密,有要求,你不能加密比秘钥更长的内容,如果用户的密码很长,那就需要一个比密码更长的秘钥去加密,超大的秘钥存储和计算都会有压力,所以我是先用非对称去交换一个对称秘钥,后续使用对称加密
    zsj1029
        20
    zsj1029  
       2023-07-14 22:37:55 +08:00 via iPhone
    Aes 两个变量 iv 和 key ,iv 前后端约定固定住,
    Key 的值登录前向后端请求,每次加密都会变,用不用 HTTPS 都可以防止拦截破解,当然本质没有解决前端不了解密的问题,只是相对增加了破解难度
    IvanLi127
        21
    IvanLi127  
       2023-07-14 23:36:18 +08:00 via Android
    这测评机构是不是有点呆,还得告诉他用 https 了。。
    https 肯定是 ok 的,测评机构自己也认。自己写还得维护,出了问题还得负责。要是有人说 hash 一下传给后端,绝对是想当临时工
    echo1937
        22
    echo1937  
       2023-07-14 23:56:21 +08:00 via iPhone
    在安全部门的检查中,针对全链路 https 还要求加密的情况,基本都是 base64 应对,他们居然认可。
    OutOfMemoryError
        23
    OutOfMemoryError  
       2023-07-15 00:36:02 +08:00   ❤️ 1
    我们甲方是某省级联通...要求 https+非对称加密传递密码信息
    dayeye2006199
        24
    dayeye2006199  
       2023-07-15 03:24:47 +08:00
    不要重复发明 https 啊
    Jirajine
        25
    Jirajine  
       2023-07-15 04:09:52 +08:00
    说你明文传输,英国指的是你前段把用户的秘密明文发送给后端,后端无论是保存明文密码还是进行各种各样的加密、hash 都是不安全的。
    密码的作用只是验证,出于最小化原则,因为服务器不需要知道用户的明文密码,所以服务器应该对用户的明文密码保持 zero knowledge 。也就是在**前端**把用户的密码 hash (加固定盐甚至不加盐也不是很大的问题)后向后端发送 hash 进行验证即可。
    不要听信#11 这样的暴论,这种做法除了增加复杂度和向用户掩盖哪些内容被传输以外没有实际意义,服务器仍然有能力访问到用户的明文密码,和 https 内明文传输没有任何区别。
    dearmymy
        26
    dearmymy  
       2023-07-15 07:54:35 +08:00
    你根本就没明白 https 跟文本加密各自的作用。
    防的人都不一样。
    https 假设是用户是君子,防止其他小人篡改 记录。
    文本加密是假设用户里有小人。他们可以很随意做出协议登录。爬虫等。
    如果你认为公司产品没啥值得被爬,没灰黑产盯着,那 https 就足够了。
    GuuJiang
        27
    GuuJiang  
       2023-07-15 08:15:29 +08:00 via iPhone
    @Jirajine 你这个恰恰才是最典型误解(同时也是一个非常普遍的误解),原本的“后端不能存储明文”的方案指的是设置密码以及验证密码时前端传输明文,后端进行 hash 后保存,这样即使被脱裤后也无法直接得到明文
    而按照你的说法,前端进行 hash ,后端保存这个 hash 值,那么这个 hash 值本身是不是就相当于明文了?不用纠结是不是用户输入的那个明文,在登录流程里它的角色就是明文,被脱裤以后压根就不需要关心真正的明文是什么,直接拿这个 hash 值来登录就行了
    Jirajine
        28
    Jirajine  
       2023-07-15 08:51:21 +08:00
    @GuuJiang 首先,存储 hash 而非明文密码防的主要不是一方登录,而是使用相同密码的用户在一个网站被脱裤,密码被攻击者用来对所有其他网站撞库,攻击者已经有了用户的明文密码,无论这些网站使用怎样的安全措施都无法避免影响。

    前端 hash 而非后端是因为最小化原则,后端能得到明文密码,也可能因为日志、内鬼、漏洞等原因泄漏,所以后端不得到明文密码这种不需要得到的信息才能最大化减少攻击面。

    至于防止脱裤后一方登录,后端可以再进行 hash ,和前端 hash 互不干扰。并且这种情况一方网站也更容易处理,更新安全策略、通知用户改密码等。

    最后你说的关于反爬、防用户,则是完全不相干的领域。况且你对登录过程加密对反爬也没有什么意义,爬虫可以用浏览器模拟登录然后取得 cookie 。
    iOCZ
        29
    iOCZ  
       2023-07-15 09:38:15 +08:00
    如果加密后再通过 HTTPS 传输,那就要加一层加密解密,好处是即使被抓包也不会泄露。如果做了 SSL pinning ,那样就不会被抓包,也就不需要加一层加密解密。但是 SSL pinning 还是挺麻烦的,如果是校验的是证书,你换了证书客户端就挂了,必须升级。如果是限制公钥,那可以换证书。
    HelloAmadeus
        30
    HelloAmadeus  
       2023-07-15 10:36:32 +08:00 via iPhone
    用 https 同样的方式加密一下最安全,不要信任用户浏览器的根证书,自已维护。密码前端 hash 后传给后端记得加盐,后端 input 没有明文密码,防撞库
    qwq11
        31
    qwq11  
       2023-07-15 12:17:55 +08:00 via Android
    直接 https 明文,参考 github 等网站就行。
    前端 hash 没必要,等于是 hash 了之后等那串 hex 是用户真正的密码,MIMA 该拦截拦截,该修改修改,该重放重放。
    RSA 更没必要,既然谁都能拿到公钥,那么加密就跟 hash 是一样的了,谁都可以加密,MIMA 该拦截拦截,该修改修改,该重放重放。
    所以传输安全也就建立在 TLS 之上,#1 的 SSL Pinning 是唯一的保障。所以想要绝对安全你可以用自签证书,不过自签证书现在用在了微信支付、支付宝支付之类的资金安全上,对于登录安全大可不必,加个 2FA 比搞这个好的多
    qwq11
        32
    qwq11  
       2023-07-15 12:21:22 +08:00 via Android
    还有一个加 nonce 的方法忘了说了,hash(nonce + hash(password)) 也算是比较安全的方式,即使没有了 SSL Pinning ,也能保证安全,不过好像用的不太多?
    MigrantWorkers
        33
    MigrantWorkers  
       2023-07-17 11:48:00 +08:00
    @renfei 抱歉 没审题,我们登录接口不加密 走 https ,我觉得也不用加密。就两种方式,账号密码验证,手机验证码验证。设置客户端登录错误次数、接口限流。感觉这样就够了吧
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   824 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 21:35 · PVG 05:35 · LAX 14:35 · JFK 17:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.