一个想法 用非对称加密算法登录

2017-05-09 16:00:30 +08:00
 pwn
登录依旧是用账号密码
客户端用账号密码生成私钥
服务器端储存账号及其对应的公钥

登录过程:
1. 客户端发送登录请求
2. 服务器端返回任意字符串( nonce )
3. 客户端利用私钥生成函数和用户输入的账号密码生成私钥
4. 客户端用私钥对 nonce 签名,并把账号和签名发送给服务器端
5. 服务器端接收账号,找到对应的公钥,并用公钥验证签名

之所以有这个想法是因为现在的密码是用 HASH 函数加密后储存的,可以被爆破,所以才有撞库这种攻击方法。但是如果只是存公钥的话,就比较难被爆破了(虽然也存在可能性,但不高)。而且可以选择的算法有 RSA,还有 ECDSA 等其他的算法,都挺安全的。

只是不知道 非对称加密算法 和 散列算法 那个性能高一点,不过如果真的很安全的话,牺牲一点性能应该没什么问题吧。
5669 次点击
所在节点    奇思妙想
26 条回复
xing393939
2017-05-09 16:03:36 +08:00
你这有一个前提条件就是用户每次只会用这一个客户端注册账号和登录账号对吧
pwn
2017-05-09 16:07:40 +08:00
@xing393939 一个产品可以把自己的加密方式确定下来,这样的话对于用户来说就和其他的登录方式没什么区别了,像往常一样登录,只是服务器的数据库那里存的不是密码散列,而是公钥。要是自由点的话可以让用户选择自己喜欢的加密方式,不过这样的话,产品应该是面对懂点密码学的用户。
ipwx
2017-05-09 16:09:06 +08:00
acess
2017-05-09 16:12:43 +08:00
没搞清楚 LZ 说的……
首先……用户名密码怎么生成非对称密钥对?

还有,暴力破解 Hash 算法难道容易么?
能暴力破解,是因为用了彩虹表等手段(按我的理解它顶多算个体积超小的高效“字典”,制作它时还是需要付出苦力的,而且能覆盖的密码长度也很有限)
有时候用户的密码是 123456 之类容易猜的,或者已经通过别的途径泄露了,所以才有“撞库”之类手段,这不表示 hash 算法不安全吧。
tony1016
2017-05-09 16:49:31 +08:00
你用私钥登录 SSH 不就这个逻辑嘛
jybox
2017-05-09 16:52:27 +08:00
U2F 也和你描述得差不多 https://en.wikipedia.org/wiki/Universal_2nd_Factor
其实 RSA 之所以比密码安全还是因为 RSA 的密钥太长了,而这么长的密钥根本不可能记住,所以密钥的存放又是另外一个问题了。
jybox
2017-05-09 16:53:12 +08:00
补充一下我上面说的「更安全」是指爆破难度更高。
goodbest
2017-05-09 17:01:21 +08:00
看一下 mega.nz
mengzhuo
2017-05-09 17:09:29 +08:00
你们都没有用过银行的电子证书么……
monsterxx03
2017-05-09 17:11:54 +08:00
starcom 就能用证书登陆啊
pwn
2017-05-09 17:24:57 +08:00
@ipwx 我的目的就是想不让服务器存密码散列,觉得这样不安全。
@acess 这只是一个初步的想法,RSA 是随机的选择大质数,而我是想凭借着账号密码来定向选择大质数,这就可以保证用同样的账号密码能登录。另外,我认为 hash 算法被破解是迟早的事,虽然现在有很多 hash 算法,而且如果用这个登录的话,彩虹表攻击是无效的。
@tony1016 我是参照 ssh 私钥登录的,但是私钥容易遗失,一旦遗失了就无法登录了,为了避免这个问题,私钥是需要用的时候才生成的。
@jybox 私钥是需要使用的时候才生成,所以不要保存私钥,但是要想出一种方法保证每次生成的私钥都相同。。
geelaw
2017-05-09 17:39:00 +08:00
所以 (公钥, 私钥) = F(用户名, 密码)?

那不还是一个 hash 函数?只不过你换了一个 hash 函数。

加盐不好么?
hxsf
2017-05-09 17:55:22 +08:00
@pwn #11 `hash 被破解`? 一个信息熵减少的算法还能逆向?

`彩虹表攻击是无效的` (公钥, 私钥) = F(用户名, 密码) 和 加盐的 hash 有啥区别么?

`但是私钥容易遗失,一旦遗失了就无法登录了,为了避免这个问题,私钥是需要用的时候才生成的。` 还不是每次生成的都一样,拿到你的账号密码和直接拿到你的私钥一样吧?

你可以选用散列值很长的 hash 函数,和很长的盐,一样可以达到效果
vainly
2017-05-09 18:05:55 +08:00
1.登录之前获取 salt
2.客户端通过 salt 对密码进行加密
3.服务端通过 salt 对密码进行解密
4.翻译结果

数据库中存的是 客户端加密后的 + 服务对称加密后的密码。
这样依赖,即使脱裤,如果不知源码中的 密匙也是无法破解的,即使知道源码中的密匙,因为客户端用的是不对称加密,还是无法获取密码原值。
mrtctl
2017-05-09 18:38:02 +08:00
凭借账号密码生成大质数这一点应该是很难实现的。质数本身就不是通过某种公式生成出来的,只能筛选出来。

倒是可以生成私钥后用用户的密码加密。
pwn
2017-05-09 18:49:39 +08:00
@geelaw 这个方法是没有摆脱账号密码登录的这个体系,这是我认为这个方法的缺点之一,但我觉得最起码这个比 hash 好,因为两个一样密码的 hash 值是相同的,而采用这种方法两个一样的密码它们的公钥是不相同的。

@hxsf hash 不能逆向,但是之前看到 MD5, SHA1 都被破解过,虽然不知道具体用什么方法,所以觉得迟早会被破解,时间问题,暂时 SHA25, SHA512 这些还能安全比较久。

区别就在于`两个一样密码的 hash 值是相同的,而采用这种方法两个一样的密码它们的公钥是不相同的`。

拿到你的账号密码和直接拿到你的私钥是一样的,没有摆脱账号密码体系是这个方法的缺点。
pwn
2017-05-09 18:54:49 +08:00
@mrtctl 这样啊....那这个登录方法就不太可行了,我上学期学了密码学导论,没有讲得很细,所以就先假设有这个凭借账号密码生成大质数方法,这个方法也是登录的核心,既然没有的话,那只能想其他方法了。谢谢您了。
metowolf
2017-05-09 19:45:29 +08:00
最好不要储存原密码!
只储存散列值,然后你爱怎么加密都可以。
geelaw
2017-05-09 19:54:56 +08:00
@pwn #16 你加盐就可以让同一个密码的 hash 不同了。而且你这个方法和加盐的 hash 没啥不同,只是有一个特殊的:你的盐是用户名的函数。

@vainly #14 你这个模型里,攻击者不需要知道密码,只要知道密码加盐之后的 hash 即可。
coyove
2017-05-09 20:02:26 +08:00
类似的想法我很早以前就实现过了,基于 openpgp.js,过程比你的简单一些

服务器端随机生成密码,用公钥加密传给前端,前端用自己的私钥解密后用该密码登录,公钥在注册时上传

https://github.com/coyove/Libay/blob/master/auth/auth.go

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

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

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

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

© 2021 V2EX