我也搞了一个密码管理器,浏览器端 AES 加密

2015-08-09 15:23:02 +08:00
 zzy8200

看了@jinyue524 同学的帖子: https://www.v2ex.com/t/211811
想起自己以前也写了一个密码管理器,不过代码就一直扔在GitHub没有管了。现在稍微改了一下发上来看看有没有人感兴趣。

GitHub地址: https://github.com/zeruniverse/Password-Manager

与@jinyue524 同学的实现差别:
1.没有PIN,只有登陆密码,AES加密以登陆密码为key
2.服务器端储存密码签名,不储存密码
3.AES加密在浏览器端做,服务器无法解密(具体机制下面介绍)。这也意味着忘记登录密码就和数据说bye-bye了
4.自豪地采用银河系最佳编程语言PHP
5.前端很难看,会写PHP的C++程序员不是好前端

下面介绍实现逻辑:

首先有两个不同的SALT,salt1和salt2
密码签名:sha512(登录密码+salt1)
AES密钥:sha512(登录密码+salt2)
AES密文,iv及crypto-js产生的salt上传服务器

注册或登录时浏览器提交密码签名,将用户输入的密码加密后存在sessionstorage里,服务器传回数据后计算AES密钥解密,因为sha512不可逆,因此签名无法算回密码。

CRYPTO-JS能将密钥转化为一个256位的key

Wikipedia说sha512和aes256在可预见的未来都是安全的

服务器端还做了一个自己写的加密(可能是哪抄的?忘了)再存入数据库,目的是隐藏AES特征。如果数据库被hack,代码没被脱裤的话看不出是aes加密

为了防止社工,密码库内账号密码都作aes加密,服务器端只以id区分。

修改登录密码目前的做法是浏览器扒下所有数据解密然后用新密钥加密后传回服务器,速度较慢

已经实现备份功能,但恢复备份功能没时间做,如果用的人多的话下个版本再加入吧

刚才自己机子上测了,明天搭个demo server。
有兴趣的同学可以自己搭着玩(用到了PDO,所以要PHP5),如果有逻辑漏洞请一定要告诉我。

项目地址: https://github.com/zeruniverse/Password-Manager

4384 次点击
所在节点    分享创造
19 条回复
zzy8200
2015-08-09 15:31:04 +08:00
由于解密需要的密钥不会传向服务器,因此使用HTTP协议也是安全的
neilp
2015-08-09 15:43:36 +08:00
支持一个
Septembers
2015-08-09 16:09:25 +08:00
建议将SHA512更换为更好的SHA3-512
raincious
2015-08-09 16:16:30 +08:00
@zzy8200



NO... NO... NO...

或许有人可以在HTTP通讯里插入另一段Javascript将解密后的密码发送走……
zzy8200
2015-08-09 16:22:52 +08:00
@raincious 中间人攻击……好吧,确实https更好
publicID001
2015-08-09 16:24:33 +08:00
@raincious 哈哈哈哈哈打脸太狠
xierch
2015-08-09 16:30:51 +08:00
AES key 用 PBKDF2 生成会不会更科学一点?
ryd994
2015-08-09 17:28:01 +08:00
@zzy8200 真有人干过http://zone.wooyun.org/content/2507
zzy8200
2015-08-10 09:51:10 +08:00
@xierch 已加入TODO

@ryd994 全局shadowsocks...
ryd994
2015-08-10 11:38:05 +08:00
@zzy8200 浏览器加密毛用没有
我要攻击的话,何必管原密码?直接穷举加密密文就行了。
ryd994
2015-08-10 11:52:57 +08:00
安全方面真心不要自己造轮子,希望这篇文章能给你一些帮助: https://crackstation.net/hashing-security.htm
zzy8200
2015-08-10 12:48:05 +08:00
@ryd994 AES-256不是那么好穷举的。虽然自己做的东西可能会有漏洞,但怎么说也比随便找个软件用放心。像lastpass这种服务商虽然可能用了更好的加密算法,但hack那个的收益显然要大很多。所以综合来说安全性不一定高。

最后:我并没有自己写加密算法。AES和SHA都是用库做的。只是用轮子造了个车罢了
ryd994
2015-08-10 13:00:36 +08:00
@zzy8200 你可以看看上面提到的文章里 “In a Web Application, always hash on the server” 一段
zzy8200
2015-08-10 13:26:04 +08:00
@ryd994 我已经看过了。我当然考虑过这个问题。

但是用来解密AES和用来登陆校验的hash函数是完全不同的。用来登陆的hash是sha(密码+salt1),用来解密AES的hash是sha(密码+salt2)。因为salt1和salt2不同,所以就算攻击者拿到hash登陆了服务器,他也无法解密服务器传回的数据。因为他必须解密密码,然后重新计算+salt2的hash。

当然@raincious 说的很有道理,必须使用HTTPS,如果攻击者能修改JavaScript那么这一整套系统的安全性会直接崩溃。
breeswish
2015-08-10 13:43:24 +08:00
建议做成浏览器扩展…否则恶意浏览器扩展轻松破解
breeswish
2015-08-10 13:47:59 +08:00
另外登录流程为何如此复杂。。
服务器只存储“密码”的 ciphertext,客户端只存储“密码”的 key,其他登录注册流程和普通网站一致似乎就可以确保:
1/ 服务端无法破解存储在服务端上的密码密文
2/ 客户端无法破解服务端上其他客户的密文
zzy8200
2015-08-10 13:49:25 +08:00
@breeswish 做成浏览器扩展恶意软件依然破解。如果木马能截屏怎么着都没用。所以建议只在信任的设备(如自己的手机)上登陆
zzy8200
2015-08-10 13:51:26 +08:00
@breeswish 因为“密码”的key是根据登陆密码算的,这样节省了一个PIN的麻烦。所以注册和登陆的密码只能留在本地。
76
2016-09-02 16:50:00 +08:00
https://app.keeweb.info/ 现在用这个

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

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

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

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

© 2021 V2EX