口令在信道中传输时不会被窃取(就是未被安装伪造证书的 HTTPS ),但服务端被攻破
攻击者得到了用户的口令明文,可以去其他站点尝试输入登录
攻击者得到了用户的口令哈希,可以构造请求去其他站点尝试登录
攻击者在拿到服务端日志或执行权限时,可能获得口令哈希,然后构造请求去其他站点尝试登录
例如,前端用SHA256($password + $hostname)请求登录,服务端用SHA256($hash + $salt)存储。
攻击者可能得到请求的哈希值,但因为加盐的存在,即便用户在其他站点使用相同口令,也无法重新计算哈希构造请求登录
第 4 种方法是最安全的。当然我们作为用户,还是每个站点都使用独立口令最好
后记:刚拔完智齿,闲得无聊,把很久以前的思考整理成文
     1 
                    
                    processzzp      2024-08-03 13:59:36 +08:00    SRP 可以了解一下,比你自己在那里闭门造车安全多了 
                https://en.wikipedia.org/wiki/Secure_Remote_Password_protocol  | 
            
     2 
                    
                    FengMubai   OP @processzzp 你说的对。我想说的并不是如何实现,只是在 v 站有过很多次关于“HTTPS 还要不要加密口令”的讨论,我现在有了闲心跟进讨论 
                 | 
            
     3 
                    
                    aababc      2024-08-03 14:14:51 +08:00 
                    
                    咋感觉少了一种情况,就是 明文请求,hash 存储 
                 | 
            
     4 
                    
                    Overfill3641      2024-08-03 14:15:25 +08:00 
                    
                    用户肯定是希望站点安全保管账户信息...... 
                 | 
            
     5 
                    
                    msg7086      2024-08-03 14:16:26 +08:00 
                    
                    这话题好像每次都会变成吵架贴呢…… 
                 | 
            
     6 
                    
                    FengMubai   OP @aababc 和第 2 种实际上是一样的,因为假设信道是安全的,只是执行哈希计算的位置不同 
                 | 
            
     7 
                    
                    clf      2024-08-03 14:29:24 +08:00 
                    
                    哈希加盐存储,明文请求 
                快进到不允许密码登录,只能验证码/扫码/第三方 oauth  | 
            
     8 
                    
                    aababc      2024-08-03 14:32:08 +08:00 
                    
                    再结合前两天看到的,密码门锁的 虚位密码 感觉又是另一种情形了! 
                 | 
            
     9 
                    
                    Puteulanus      2024-08-03 14:43:58 +08:00 
                    
                    既然服务端已经被攻破,那你怎么防止攻击者直接修改你的前端代码来从用户手里获取明文密码呢 
                 | 
            
     10 
                    
                    FengMubai   OP @Puteulanus 说得好,但不影响第 4 种方法是这 4 种里最安全的 
                 | 
            
     11 
                    
                    herbertzz      2024-08-03 14:56:16 +08:00    Challenge - Response 模式,连密码都不用传 
                 | 
            
     12 
                    
                    jinliming2      2024-08-03 17:03:47 +08:00 via iPhone    HTTPS 下面传明文就足够,其他轮子意义都不大。 
                在不破坏 HTTPS 的情况下,明文不会有问题。 在 HTTPS 被破坏了,比如中间人,或者 HTTPS 用了过时不安全的算法,那么: 传 HASH:直接截取重放即可。 传带时间戳的 HASH:要求服务端明文存储用户密码。 用加密算法加密:不管对称还是不对称,都需要给客户端下发加密密钥,HTTPS 被破坏的情况下,中间人可以替换下发的密钥,做代理。 客户端预置密钥/公钥:你重新实现了 TLS 。  | 
            
     13 
                    
                    R4rvZ6agNVWr56V0      2024-08-03 17:08:55 +08:00 
                    
                    Okta API 传的是明文,我想世界上没有第二家比之规模更大的身份管理厂商了吧。 
                 | 
            
     14 
                    
                    murmur      2024-08-03 18:47:08 +08:00 
                    
                    base64+https 就可以了,https 都被劫持了你的 js 文件是不是真的都是两回事,base64 完全是为了对付等保 
                上次有个等保扫我们,说我们所有的 api 路径都用了明文,无语,还专门写了个代码把所有的接口地址都改成\xx\xx\xx\xx 这样的写法  | 
            
     15 
                    
                    FengMubai   OP @jinliming2 你说的对,但是你完全忽视了我的假设 
                 | 
            
     16 
                    
                    wOuv7i4e7XxsSOR1      2024-08-03 21:30:24 +08:00 
                    
                    不知道你在说什么,就算攻击者得到用户的口令哈希,他怎么去构造请求登录其它站点?你该不会以前口令哈希是前端请求的时候构造的吧? 
                 | 
            
     17 
                    
                    wOuv7i4e7XxsSOR1      2024-08-03 21:30:32 +08:00 
                    
                    不知道你在说什么,就算攻击者得到用户的口令哈希,他怎么去构造请求登录其它站点?你该不会以为口令哈希是前端请求的时候构造的吧? 
                 | 
            
     18 
                    
                    wOuv7i4e7XxsSOR1      2024-08-03 21:36:50 +08:00    还有你这第四种,“前端用 SHA256($password + $hostname)请求登录,服务端用 SHA256($hash + $salt)存储”,你要不好好看看你在说什么? 
                 | 
            
     19 
                    
                    Nosub      2024-08-03 21:39:44 +08:00 via iPhone     | 
            
     20 
                    
                    chinni      2024-08-03 21:46:26 +08:00 
                    
                    我见过的一个网站就是 每次先请求一个 rsa pubkey 然后用户密码加密后传到后端 反正后端有 privkey 解密..  存的话怎么存都行了 反正能比就好 很多成功例子 
                 | 
            
     21 
                    
                    Chemist      2024-08-03 21:46:45 +08:00 
                    
                    TLS 是传输层加密,传输层不可靠那就只能再往上一层那就是应用层加密了。 
                服务端的应用层那就是源码级加密。程序用私钥加密,通过启动器从环境变量加载公钥启动应用。这样即使攻破服务器也查看/修改不了源码,从而保护业务逻辑。 浏览器 -> 服务端则要求用户注册的时候保存用户的公钥,之后所有的请求需要用户私钥加密传输。服务端使用用户注册的公钥解密请求。这样只要保证用户注册时是安全的即可。用户的公私钥对要可以通过 yobikey 之类的东西实现。没错,就是以前的网银盾。  | 
            
     22 
                    
                    murmur      2024-08-03 21:47:55 +08:00 
                    
                    @jdkxnktkdkxod 很明显楼主连加盐都没搞清楚,这玩意只能防止脱库后被逆出明文密码,然而现在是全实名制,人家已经改了 https 证书,进了你的服务器,就可以拿到代码逆向出手机号、身份证等更多数据 
                怎么说呢,除了不能给彩虹表提供数据,真的惨  | 
            
     23 
                    
                    EndlessMemory      2024-08-03 21:54:23 +08:00 
                    
                    散列值+盐就行了,没有绝对的安全,增加攻击者的成本就行了 
                 | 
            
     24 
                    
                    FengMubai   OP @jdkxnktkdkxod “+”为自定义运算,你可以用简单的字符串拼接,$hostname 代表着前端的盐是一个公开的固定的值,$salt 是来自随机数发生器的和哈希等长的盐。也就是说,即便用户使用相同的口令,那么服务端接受到的请求中的口令字段,也无法用于去撞隔壁的站点;服务端再次加盐,就是常规目的了 
                 | 
            
     25 
                    
                    FengMubai   OP @murmur 很显然你并没有理解我想讨论什么。我并没有说这样做可以保护服务端被攻破时避免数据泄露,我只是想讨论,口令要如何传输(当然不传最好 
                 | 
            
     26 
                    
                    murmur      2024-08-03 22:44:26 +08:00 
                    
                    @FengMubai 你想太简单了,我都上了你服务器了,你的代码还是你写的么,我如果不想搞你直接删库留个比特币的勒索条子,想搞你我代码都可以给你改掉 
                你的前提是服务器被“我”攻破,那你所有的代码还是你之前写的吗  | 
            
     27 
                    
                    FengMubai   OP @murmur 你说的对,你想的很全面,但是如果不设置一个假设范围的话,任何讨论都将没有讨论的意义 
                 | 
            
     28 
                    
                    huihuimoe      2024-08-03 23:01:19 +08:00 
                    
                    草,服务端都被攻破了,你还想着正经拿 post 内容构造??? 
                直接改服务端插点 js 直接把所有用户动作上报不就好了,想要啥东西都给你传回来啊  | 
            
     31 
                    
                    EminemW      2024-08-03 23:08:25 +08:00 
                    
                    @jinliming2 那啥,服务端就不应该明文存用户的密码,存明文密码有点窥探用户隐私的意思了 
                 | 
            
     32 
                    
                    keithwhisper      2024-08-04 00:01:06 +08:00 
                    
                    方案 4 比较有责任心, 不过大部分开发是没有这个心思的. 
                用户密码明文出现在服务端一侧, 就可以被社会工程学攻击, 以前就有过用户密码明文被日志记录的例子. 当然, 有人会骄傲地说, "你们日志不去敏, 你们不专业", 他们应该去看一下 "墨菲定律" > Anything that can go wrong will go wrong.  | 
            
     33 
                    
                    hubaq      2024-08-04 00:06:26 +08:00 
                    
                    服务端都被攻破,任何安全手段都是脱裤子放屁 
                 | 
            
     34 
                    
                    panda1001      2024-08-04 00:07:55 +08:00 via Android 
                    
                    前端 js 混淆后加密提交参数,至少增加了爆破门槛 
                 | 
            
     36 
                    
                    MFWT      2024-08-04 00:19:38 +08:00 
                    
                    我可能有点敏感,不过我写的小项目也是用的方法 4 ,防重放肯定是做不到,但至少可以让明文密码不离开用户机(你说用户机被攻破了.......那算了) 
                 | 
            
     37 
                    
                    SP00F      2024-08-04 00:27:49 +08:00 
                    
                    😰 没有讨论的价值,服务器都破了。拿着你最高权限都懒得管你加不加密了 
                 | 
            
     38 
                    
                    FengMubai   OP @SP00F 看你愿不愿意把“当自己的服务被攻击时,保护用户在其他在站点的账户不被波及”当作安全义务了 
                 | 
            
     40 
                    
                    22F41628gA98q4Lx      2024-08-04 06:56:17 +08:00 
                    
                    首先客户端的代码,花时间肯定能知道你的逻辑。 
                其次,服务器被攻破,花时间也肯定能知道服务器代码的逻辑。 因此,上面四种方案属于脱裤子放屁。  | 
            
     41 
                    
                    FengMubai   OP @Tstxxy 现密码学的思想是:算法可公开,安全性靠密钥保证,对于非对称密码甚至可以公开密钥,哈希密码甚至没有任何必须隐藏的东西了。你再花时间想想 
                 | 
            
     42 
                    
                    byte10      2024-08-04 08:38:05 +08:00 
                    
                    @Tstxxy  😂,很多人都是这样想的。 
                楼主我再告诉你 2 个案例,有人说 cookie 不安全,别人登陆你电脑拿到 cookie 就可以登陆你淘宝。还有人说家里的门不安全,因为你钥匙掉了,或者被偷了就会被盗窃。 你提出的问题 跟上面没啥区别。目前市面 95%的 app ( web )都不会通过客户端加密来请求登录的(当然做了是更好),微信和支付宝虽然我没研究过,但是花 5000 块钱 肯定是可以拿到你说的那些啥前端加密的方式😂 。 有安全级别比较高的 app ,比如支付宝,他们就需要你的人脸识别,短信验证等。  | 
            
     45 
                    
                    Anarchy      2024-08-04 09:14:23 +08:00 
                    
                    这些逻辑都基于把密码当做用户隐私做安全措施,那用户隐私是什么级别的安全防护?当然明文存了。 
                 | 
            
     46 
                    
                    DeWjjj      2024-08-04 09:37:25 +08:00 
                    
                    在登入系统独立的情况下,密码可以由多个字段处理管理。 
                例如捆绑 ip ,换 ip 验证信息丢失。 验证器,例如谷歌等。 手机验证码,小金额保护。 人脸验证,大金额保护。 安全措施很多,不仅要只做密码一层。  | 
            
     48 
                    
                    ifbluethen      2024-08-04 10:58:44 +08:00 
                    
                    4 感觉拿到 hash 后的密钥就能用 api 工具伪造请求,只是没有明文密码而已吧 
                 | 
            
     49 
                    
                    jinliming2      2024-08-04 11:14:14 +08:00 via iPhone 
                    
                    抱歉抱歉,确实没仔细看假设。 
                不过,对于 Web 业务,如果服务端被攻破,那么就完全有能力改造用户端的登录页面,直接去除 hash 逻辑,把明文带上来。 当然,这里假设服务端被攻破是指能控制前端代码的服务端被攻破。  | 
            
     50 
                    
                    ryanlid      2024-08-04 13:29:01 +08:00 
                    
                    服务器被攻破了,别人在下载用户数据,你却在破译用户密码 
                 | 
            
     51 
                    
                    lthon      2024-08-04 16:14:57 +08:00    如果基于 Kerckhoffs's principle ,那么不能依赖客户端的服务器不被攻破,所以方案 3 和 4 是一样的。 
                搜索到 https://crackstation.net/hashing-security.htm ,这篇文章说得非常好,建议得方案比 OP 第 4 种稍作了一些变化,前端的 hash 函数使用标准密码哈希函数(例如 Argon2 、bcrypt 、scrypt 或 PBKDF2 )而不是 SHA256 ,目的是减慢 hash 速度。  | 
            
     53 
                    
                    wdssmq      2024-08-04 21:56:00 +08:00 
                    
                    
                 | 
            
     54 
                    
                    SP00F      2024-08-05 00:19:48 +08:00 
                    
                    @FengMubai #38 首先要考虑的是如何防止数据泄露、数据脱敏、服务器最高权限被拿下。再去考虑密码的问题,即便没有拿到最高权限,当渗透的主要目的只是脱裤的时候,最高权限不是对方的目的,对方的目的可以通过供应链、劫持等渠道篡改部分前端代码( Web ),在构造请求前就可以把活跃用户的账号密码“脱”下来。 
                还有做埋点记录的,这一块属于供应链侧的攻击,你要考虑你的用户群体是否存在被脱裤的价值,如果有那优先考虑如何防止在低权限的情况下甚至不是以攻击你方服务器的情况下获取到用户信息。 担心在传输过程中出现问题得考虑中间人的问题,再去加密即可。 安全是无形的成本,钱嗷嗷花,东西看不见。出问题的时候这钱花得又觉得不值,老板高管不懂安全的又要骂又要砍。 为什么小公司几乎都不会考虑更深的安全问题就在这里了。即便大公司,说实话的,当攻击面扩大的时候,已经不是考虑密码传输加密不加密的问题了。  |