用户登录接口的设计,简单的功能不简单 [干货!原创文章禁止转载!]

  • 很多系统在登录的时候会使用明文密码的方式往后端进行传参,即使传输过程中使用的是HTTPS,但是如果在中间人攻击中,或者钓鱼网站。攻击者过于轻松的从中截取到明文的密码。

  • 用户登录后的权限的Token或者Cookie会用明文的方式在HTTPS上进行传输,其实如果出现上述场景太容易出现问题。

  • 输入密码场景,在Web 前端进行明文加密后进行传输是否有意义?

    • 必须要做,虽然不是决定性的保护措施,但却是很有意义的低成本安全增强方案。
  • 在登录后的有权限的接口上建立在HTTPS上是否需要在应用上层实现加密是否有意义?

    • 如果有开发资源的情况下,建议需要做。
    • 在开发资源不宽裕的团队中在无权限接口场景中,不建议使用密文传输,但是建议加入签名机制防止传输过程中篡改。主要原因是如果是密文传输,中间内容不可见。会直接影响到调试过程,导致开发成本的提升。另外如果接入一些三方系统时,比如WAF,日志,路由等,因为内容不可见,可能会导致早期开发成本较高。所以退一步,加入签名机制,传输过程中虽然明文可见的,但是可以保证数据的完整性,签名过程中加入过期时间,也可以在一些场景下防止请求被重放,在一些要求限制请求延迟的接口中还可以。
  • 在所有接口上建立加密传输,或者签名是否需要做?

    • 如果开发资源丰富的情况下,建议需要做。
    • 在开发资源不宽裕的团队中在公开接口场景中,基于HTTPS时不暂时做过多的开发。
  • 所有场景,加密总会比不加密要安全,但是必须考虑的是开发成本和收益的问题

  • 敏感操作需要使用,2FA是一个比较有效的解决方案,一定要注意防重复的问题。当然如果在中间人攻击中如果中间人篡改的源码,那么这些防御基本都会失效,所以搭配App扫码验证的的方式就有很好的效果。

  • 在权限接口中肯能会出现的风险

    • 窃听风险(eavesdropping):第三方可以获知通信内容。
    • 篡改风险(tampering):第三方可以修改通信内容。
    • 冒充风险(pretending):第三方可以冒充他人身份参与通信。

实践

这里提供一个解决思路,可以适用于一些场景,需要按照具体场景进行适配。还有一个备选的方案,在 https 上做一层类似https的协议,https比较安全的原因很大一部分是证书有效性的验证依赖于操作系统,但是如果没有的操作系统的验证,如果单纯的类似https的协议,收益不大,所以这个实践中就融入了业务的流程。

服务端信息存储的设计

  • 用户名/邮箱/手机号存储:关于用户信息的保存,这里可能有些做法中会选择使用对称加密的方式保存,这里需要注意的是开发成本和收益,建议使用明文保存全文(应对业务的变动)。业务稳定后可以选择明文保存隐藏部分内容的,(便于明文搜索),密文保存整体内容。
  • 密码的存储:必须使用单向的Hash算法,并且加盐。推荐使用Bcrypt。前端发送值为 Bcrypt( Raw ) 得到 Val_0,后端保存值为 提取Val_0的salt值为( Val_1 ),Val_1 + (Delimiter) + Hash256( Val_0 )
    • 要求1:后端是不能直接接收明文的密码的,所以前端发送的时候就必须要进行加密
    • 要求2:后端需要进行加密保存。所以这里保存之前的salt和加密后的值,这里使用了Hash256的方式进行加密,这里也可以再次使用Bcrypt进行加密,但是在Secret设计中需要获取这次Bcrypt中使用的Salt值。

请求签名的设计

这里使用Hmac的思路进行请求签名的方式。Hash( Raw + Salt ),可以看到如果按照这个思路中,前端需要保存Salt,并且后端需要持有相同的Salt,这里因为 原始的明文需要传输所以Salt尽可能不在相同的渠道进行传输,或者不传输。

技术选型:

这里使用JWT组件来做签名组件,Algorithm采用Hash256,需要加入过期时间字段。这个组件在多个平台都有成熟的实现。组件中的 Secret 可以类比成salt,基本原理和Hmac类似。这里为了防止整个请求参数被篡改,那么签名中需要有请求参数的hash值,所以在这个思路中,需要有一个比较合适的通用请求方式,所以最好是Post请求,并且所有的请求参数都放到请求体中,这样会更加便利于这个思路的实现。

signature = JWT(payload={
    "digest": hash256(RequestBody),
    "otherFields": "otherFieldsValues",
    "exp": expireTime
}, key=secretKey, algorithm='HS256')

SecretKey 的设计

现在来看可以看到,SecretKey 的安全性,成了关键,这里使用办法是将用户输入值作为SecretKey相关的生成方式。这里可以适配两个比较普遍的场景,密码登录,验证码登录。

这里主要的思路在登录过程中将用户的输入在前端计算出和注册流程中一样的值,然后将对称的值当做SecretKey使用,这样在登录流程中SecretKey就会这个值就不会出现在传输中并且一边密码的强度又比较高,所以登录过程相对会比较安全。

注册流程中, 由上述流程中可以看出如果可以在可以通过别的渠道获取到和后端一样的对称密钥,那么整个流程会安全很多,这里提供一个方式采用验证的URL的方式,这里需要注意的是密钥需要是用URL hash的方式存放到URL上,用户在注册验证的时候,点开URL,默认情况下浏览器是不会发送Url Hash # 后的部分的,只有客户端可以获取到。

流程参考:

注册流程

  • 前端输入用户名/邮箱/手机号和密码(验证码)
  • 前端收集到密码后
    • 然后再次使用Bcrypt对密码进行加密得到值 Val_0
    • 后端如果验证通过,将 Salt( Val_0 ) + (Delimiter) + Hash256( Val_0 ) 进行持久化的存储,返回成功。
    • 前端跳回登录,如果不登录的场景,前端使用登录相同的流程进行登录。(这里最好不要由后端自动登录权限)

登录流程

  • 前端输入用户名/邮箱/手机号和密码/验证码(需要加入人机验证,所有公开的写类型操作的接口必须要做人机验证,类似的发送短信、邮箱验证,登录,注册,等等,验证码的场景下验证码的强度不足,可能会被破解,可以采用字母+数字的验证,验证通过后使用当前密钥换取强度较大的密钥,但可能会被跟踪,验证码和密码登录有同等的做法)

  • 前端请求接口得到后端保存的密码的Salt的值

  • 前端收集到密码后

    • 使用Bcrypt( Raw ) 和后端取得的Salt得到值 Val_0,在进行Val_1 + (Delimiter) + Hash256 ( Val_0 ) 得到 Val_1,这样前端可以计算出和后端存储一样的值,
    • 然后 Hash256( Val_1 ) 得到 Val_2
    • 然后再次使用Bcrypt对密码使用新的Salt值进行加密得到值 Val_3
    • 使用Val_1作为Key对Val_3进行AES加密,前端需要保存Val_1这个值,如果后端验证通过,那么就Val_1 当做 Secret 来使用,
    • 后端如果验证通过,把存储中的密码Hash值作为身份的验证的SecretKey,然后把 Val_3 更新原有的密码的Hash值,并返回通过,进行后续的操作。(这里需要注意密钥的有效期,需要在上一个密钥未过期的时候来更换密钥,更换方式使用当前密钥做key然后使用对称加密的方式即可)

如有问题欢迎留言或者私信

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342