1
fffang 2019-08-27 11:27:59 +08:00
加密算法+签名校验
|
2
chendy 2019-08-27 11:32:55 +08:00 1
要么 https,要么不安全,前端做哈希做加密只能提高门槛不能保证安全
|
3
misaka19000 2019-08-27 11:33:37 +08:00
没有用,中间人拿不到密码,但是可以依然可以通过传输的数据伪造用户登录
|
4
murmur 2019-08-27 11:34:03 +08:00
rsa 不久可以了么
|
5
AngryPanda 2019-08-27 11:39:24 +08:00
下发一个 nonce,密码提交之前用它来进行非对称加密,提交密文密码给服务端。
|
6
abcbuzhiming 2019-08-27 11:40:52 +08:00
@AngryPanda 中间人攻击可以换掉你这个 nonce
|
7
SuperMild 2019-08-27 11:41:39 +08:00 via iPhone
简而言之,搞来搞去最终相当于重新发明 https。
|
8
tabris17 2019-08-27 11:42:04 +08:00 1
没有第三方根证书无法防止中间人攻击,无解
|
9
AngryPanda 2019-08-27 11:42:09 +08:00
@abcbuzhiming 是,中间人还可以截获 cookie
|
10
vcfghtyjc 2019-08-27 11:44:01 +08:00
Oauth 吧
timestamp 这个方案实际上不太可行,因为 server 和 client 之间不一定同步。 |
11
sobigfish 2019-08-27 11:45:40 +08:00
这问题就相当于没有种果树,如何吃到果子,答案就只有 2 个,自己种, 或者买(用第三方登录)
|
12
shiji 2019-08-27 11:46:32 +08:00 via iPhone
不能防中间人
时间戳只能用一次限制了服务性能 不可以明文储存用户密码 不可以用 md5 保存用户密码 你用什么保持登录状态? cookie 什么的直接抓包一清二楚,根本不需要研究你是怎么处理登陆的, 直接把 cookie 全部拷贝就有了同样的身份 ssl tls 的存在就是用来解决问题的, 严格来说你离开了它们就无法保证安全 钻牛角尖的话让用户必须使用你提供的 openvpn 登录网站, 必须使用 sshtunnel 登录网站,可以不用 HTTPS, 但是现在起作用的还是 ssl |
13
shingoxray 2019-08-27 11:49:27 +08:00
注册和登录可以通过手机短信动态一次性密码,但是登录成功后就无法抵御中间人了。
|
14
luob 2019-08-27 11:53:15 +08:00
当密文和密码本都从一条路走的时候,什么加密手段都是假的。
没有 https 的情况下,短信或邮箱快捷登录也许是个好方法。 |
15
lshero 2019-08-27 11:55:31 +08:00
使用第三方可信通道完成密码传递的过程,比如短信通道下发验证码。
验证通过后将验证码当成一个凭据存储在本地参与签名,切记不可在传递的过程中把短信验证码加入请求体,只传递参数和签名,服务端校验签名是否合法。 用户的 IP 地址和 session 或者 cookie 需要进行绑定,网络环境发生变化后需要重新登陆 |
16
msg7086 2019-08-27 11:59:11 +08:00
你说的安全,只是保证用户密码不被第三方截取的意思么。
那走第三方信道就行了,比如让用户通过短信把密码发到你短信终端,或者让用户给你发一份邮件,里面填写密码。 |
17
danmu17 2019-08-27 12:02:45 +08:00 5
又是一个典型的不知道自己在问什么的提问者。
https 的 best practice 是实现在客户端和服务端以及 CA 三方都没有被 compromise 的前提下来阻止通讯被 MIM。 所以在楼主没有误入歧途的前提下 楼主无论如何都不可能在不建立属于自己的国际标准并开发对应的服务端&客户端的前提下 实现真实的需求。 我越来越好奇是不是整个 V2EX 只有我一个不是小白同时又闲又好心的存在了。 |
18
danmu17 2019-08-27 12:11:02 +08:00
另外我也好奇是不是真的没有几个中国程序员看过 ietf。
|
19
rockyou12 2019-08-27 12:13:53 +08:00
基本不可能,不用 https 首先你前端所有代码都是明文,怎么加密都没用
|
20
abmin521 2019-08-27 12:51:27 +08:00 via iPhone
自己实现 https ? 我瞎说的
|
21
mamahaha 2019-08-27 13:01:24 +08:00
@danmu17 术业有专攻吧,前端大神也许是数据库小白,java 大神也许是区块链小白。大多数人都是抱着取长补短的态度来的吧。
|
22
hanqi7012 2019-08-27 13:06:49 +08:00 via iPhone
这么容易确保安全还要 CA 干嘛
|
23
xenme 2019-08-27 13:09:02 +08:00 via iPhone
没有 https,其他都没用。
md5 只是把用户的密码从 abc 变成了 md5 ( abc ),对中间人没有区别 |
24
cz5424 2019-08-27 13:22:23 +08:00 via iPhone 1
发明一个 https
|
25
shuax 2019-08-27 13:23:52 +08:00
rsa
|
26
arrow8899 2019-08-27 13:25:07 +08:00
https 就是干这个的啊,不明白为什么不用 https
|
27
mornlight 2019-08-27 13:25:49 +08:00
不可能。你做的任何设计,我把你网页内容换掉就行了,先把密码往其他地方发一次。
|
28
xuanbg 2019-08-27 13:35:33 +08:00
增加一个获取 code 的接口,服务端生成一个一次性的随机字符串,和用户名、密码一起计算出一个签名,算法可以简单地使用:md5(md5(passwd+account)+code),因为服务端的密码已经是 MD5 值了,所以不需要再次 md5。签名结果作为 key 保存在 redis 中(value 可以是用户 ID),然后把这个 code 返回前端。前端使用 md5(md5(md5(passwd)+ account)+code)算法就能计算出相同的签名。只需要把这个签名作为登录的唯一参数传给后端进行验证即可。后端拿这个参数去 redis 中找这个 key,找到就是验证成功。如果用户名、密码、code 任何一个参数对不上,都无法计算出正确的签名,也就不能通过验证。
中间人只能拿到用户名和 code,永远拿不到任何形式的密码。所以即使数据不加密,也是安全的。只要签名是一次性的,中间人拿到签名也没用。既不能用来登录,也无法还原出密码。 |
29
falcon05 2019-08-27 13:43:39 +08:00 via iPhone
注册的时候服务器生成密码,让用户记住
|
30
xuanbg 2019-08-27 13:47:56 +08:00 2
登录的安全主要就是中间人攻击,而中间人攻击的实现方法无非就是重放攻击。也就是把截获的数据重发一遍或者重新组装后发送,所以防范的办法就是让重放失效。
根据以上分析,唯一的办法就是引入一次性密钥,并且不直接传递任何形式的密码。只要做到这两点,中间人就无处下手进行攻击了。 |
31
wackyjazz1 2019-08-27 13:49:35 +08:00
建立 httpsr
|
32
ysc3839 2019-08-27 13:50:31 +08:00
前端 RSA 加密密码再发给服务器,不过只能防止抓包,防不了中间人攻击。
|
33
Hanada 2019-08-27 13:52:27 +08:00 via Android
@falcon05 但是注册时已经被中间人截取下发的密码就无解了,说白了,不用 https,中间人有一万种办法去搞你
|
34
lsylsy2 2019-08-27 13:56:04 +08:00
|
35
loginbygoogle 2019-08-27 13:58:38 +08:00
手机验证码登录,多简单的事儿
|
37
xuanbg 2019-08-27 14:06:11 +08:00
楼上说 https 能搞定一切的,真的研究过安全么? https 并不能防重放攻击,而登录最大的安全威胁就是重放攻击。我抓到一个登录的 https 包,原样不动发给你,token 什么的轻松到手。
|
38
Jex 2019-08-27 14:06:54 +08:00
很简单,把毫无安全常识的码农都炒掉就行了
|
39
herozhang 2019-08-27 14:07:28 +08:00
每次登录都用短信验证码
|
40
TomVista 2019-08-27 14:10:21 +08:00
手机验证码+长连接+自定义通讯协议,代码混淆一下,只有上帝才知道你发送了什么。
|
43
tankren 2019-08-27 14:17:07 +08:00
没有 https 我肯定不会成为用户
|
44
ImJoeHs 2019-08-27 14:17:59 +08:00
|
45
npe 2019-08-27 14:19:38 +08:00 via Android
没用
|
49
lygmqkl 2019-08-27 14:56:11 +08:00
非 https,想要做到 中间不被监听等于造一套 https,所以这个问题真没啥意义。。。 而且即使 https 也不是 100%安全,何况非 https
|
50
lshero 2019-08-27 15:04:50 +08:00
@lsylsy2 你说的对,在中间人面前所有的造轮子小技巧都是徒劳的,这个问题没有意义。
楼主的问题就和面试中遇到的那些奇葩的面试题题一样,所以只能从个人的理解去回答。 其实即使保证了传输安全,但是如何确保浏览器等客户端环境的安全? 否则厂商也没有必要给 U 盾加装一块屏幕显示交易信息了。 最后能保障安全的只能是 CA 买的保险以及 webtrust 对 CA 的审计还有法律对电子签名的认可 |
52
no1xsyzy 2019-08-27 15:57:58 +08:00
中间人面前都是徒劳
对付所有办法,直接插个前端录屏的审计工具(这个我记得有人发过分享创造) 有中间人,只要你访问一个没 HTTPS 的网页并且点击页面内任何位置,连剪贴板都给你挖出来 (所以其实我第一次知道剪贴板竟然是应用程序自己任意决定何时读取何时写入的时候是震惊的) |
53
luozic 2019-08-27 16:03:09 +08:00 via iPhone
模拟 https 再搞一套?
|
54
janus77 2019-08-27 16:03:39 +08:00
你这问题就相当于 没有车怎么能跟坐车的人一样准时到目的地
|
55
ipwx 2019-08-27 16:07:52 +08:00
|
56
polymerdg 2019-08-27 16:08:32 +08:00
中間都是明文 抓包 原形畢露
|
57
gamexg 2019-08-27 16:17:39 +08:00 via Android
@xuanbg 重放攻击?
我记得 ssl 握手时要求双端生成随机数,重放攻击会使得服务端随机数对不上,重放攻击失败。 |
58
gamexg 2019-08-27 16:22:38 +08:00 via Android
你需要考虑中间人是只能监听流量还是能够修改流量。
如果只能监听,那么好解决,我记得 dh 密钥交换就可以做到中间人无法获得加密密钥。 如果可以修改,那么没有除非是 https,不然不可能做到安全。 |
59
nnnToTnnn 2019-08-27 16:30:10 +08:00
保证不了谢谢,就算采用 rsa 也没办法防止中间人,除非你能解决以下问题
+ HTTP Strict Transport Security, a.k.a. HSTS (defined in RFC6797) + HTTP Public Key Pinning a.k.a. HPKP (defined in RFC7469) + DNS-based Authentication of Name Entities a.k.a. DANE (RFC6698 and RFC7671) |
60
nnnToTnnn 2019-08-27 16:32:25 +08:00
@nnnToTnnn 无法防止中间人,意味着上层路由可以盗取用户帐号密码,篡改订单数量,等等各种操作,用户对于黑客而言,没有任何隐私
|
61
nnnToTnnn 2019-08-27 16:40:05 +08:00
@xuanbg https 不能防止重放攻击,那设计这个协议出来干嘛? 闲的蛋疼,你抓一下 https 的包就知道了,握手时要求双端生成随机数
|
62
chairuosen 2019-08-27 16:46:14 +08:00
@xuanbg 重放如何获得 pre master key? 得不到
|
63
AstroProfundis 2019-08-27 17:00:36 +08:00
哪里听来的中间人就是重放...
https://zh.wikipedia.org/wiki/%E4%B8%AD%E9%97%B4%E4%BA%BA%E6%94%BB%E5%87%BB 防中间人攻击需要在通信前安全地交换一组密钥或者约定某种验证手段,用来发现流量是否被篡改,对一般 HTTPS 来说是浏览器内置的 CA 证书,如果你有办法通过线下渠道或者别的安全手段和客户端交换密钥,那就可以自己做非对称加密,如果没有(所有数据只能通过网络传输)那就老老实实用 HTTPS |
64
VensonEEE 2019-08-27 17:01:36 +08:00
各位大佬,我有一个不成熟的想法,因为客户端加密和传输基本是透明的,怎么弄都是可以模拟的。不然要 https 也没用了。如下:
一个登录分成 N 个请求,每个请求通过加密算法生成登录因子,一共 N 个,这样每个请求就成了服务端算法中的一个参数。 服务端陆续收到 N 个因子并挂起,并通过算法验证后,再一起返回结果。 只要客户端服务端设计的拆分验证算法够复杂,伪造的可能性就会非常低。 欢迎各位大佬讨论。 |
65
kuaner 2019-08-27 17:13:05 +08:00
https 就是解决链路安全的,除非你再提出一种方法保障链路安全,比方说量子通信
|
67
MrSong0607 2019-08-27 17:15:47 +08:00
|
68
litmxs 2019-08-27 17:20:19 +08:00 via Android
将 HTTP 作为一个不可靠的连接底层,在其上仿照 HTTPS 实现一层可靠的连接
|
69
youxiachai 2019-08-27 17:30:45 +08:00
楼主看的大家这么激烈,都不敢说话了....
话说,现在 https..门槛不高啊...为啥不用 https...好奇.. |
70
zjyl1994 2019-08-27 17:31:36 +08:00
为啥不能用 https 呢?你这很难搞啊,你再怎么整最后也是重复发明一遍 https
|
71
VensonEEE 2019-08-27 17:43:28 +08:00
@kuaner
@youxiachai @zjyl1994 我觉得题主应该是再内网或者无域名的环境,自签或者不受信任的证书会导致浏览器提示安全问题。 然而有些情况,比如政企网站必须通过三级等保,安全加密是必选项。 |
72
zhanggg 2019-08-27 18:00:36 +08:00 2
咱们骚起来,学银行所有用户插 U 盾怎么样
|
73
youxiachai 2019-08-27 18:02:13 +08:00
@VensonEEE 像 12306...最早不就是搞自签证书...还是得用 https 啊
|
74
liang2u 2019-08-27 18:16:35 +08:00 via Android
防中间人抓包有个思路,每次 api 请求加上验证 authcode,由 token 加时间戳 md5 计算而来,server 验证 authcode 以及单个 token 的时间戳不得重复,还有时间差控制到 N 秒,就这些。
|
75
zjyl1994 2019-08-27 18:43:43 +08:00
@VensonEEE 你这种情况签发一个 CA 强制要求下面机器信任不就行了,而且 ip 也可以签发 ssl 证书啊,这都不是自己造轮子的问题
|
76
NoKey OP @youxiachai 如果使用 https 了,一切都不是问题,就是想看看大家在非 https 环境下,有没有什么好办法,技术讨论嘛,😁
|
77
nodin 2019-08-27 18:47:06 +08:00 via Android
邮箱、短信、微信下发登录验证码
|
78
AstroProfundis 2019-08-27 18:48:10 +08:00
@liang2u #74 你这是防重放,并且牺牲了并发性能,如果中间人直接把真实请求拦截掉了再假装自己是客户端发请求给服务端呢?服务端并不会收到两次相同请求的噢
|
79
VensonEEE 2019-08-27 18:48:25 +08:00
@zjyl1994 以前 12306 就是这么干的,还写了教程挂在首页,用户多了,外加需要一些技术基础,老爷们未必能接受。现在 12306 也入大流了。具体得看业务,并没有完全完美的解决方案。
|
80
ZRS 2019-08-27 19:00:45 +08:00
没有办法
|
81
cheng6563 2019-08-27 19:37:58 +08:00 via iPhone
1.https 并不能进行重放攻击
2.因为 http 本身不安全,使用 http 进行密钥交换再加密也没啥意义。必须要另一个安全的通道进行密钥交换,比如操作系统内置的 CA ;或者直接下发短信验证码,不过短信验证码很短穷举也是分分钟的事。 |
82
monkeyk 2019-08-27 19:56:07 +08:00
SM2 非对称加密处理 / 保证安全 /一次一密
|
83
type 2019-08-27 19:56:40 +08:00
@NoKey 使用 HTTPS 就是保护链路安全,如果只能使用 HTTP 还要保护链路数据,那最终还是要实现一个类似 HTTPS 的应用层,比如:
1. 使用 [非对称加密算法] ,生成公私钥,服务端持用私钥,公钥返回给客户端; 2. 客户端生成一个 32 位随机字符串,将账号、密码、随机字符串使用公钥加密,通过 POST 请求传给服务端; 3. 服务端将收到的数据使用私钥解密,并验证账号密码是否正确,如果正确,生成 Session,将随机字符串保存在 Session 中,并使用上述的随机字符串为密钥,使用 [对称加密算法] 加密返回信息,并返回给客户端,同时返回 JSESSIONID 到客户端的 COOKIE 4. 客户端使用之前生成的随机字符串为密钥,将服务端返回的数据使用 [对称加密算法] 解密,得到登录成功的信息 5. 后续客户端向服务端请求,都使用: [对称加密算法] 加密请求内容 再请求; 6. 服务端根据请求的 COOKIE,取出 Session 中的随机字符串,将请求解密;返回信息时也全部加密返回内容 再返回客户端;(使用 [对称加密算法] ) 描述有点混乱,大概就这么个思路,主要是按楼主的想法:保护客户端和服务端的交互信息; 随机字符串长度跟使用的 [对称加密算法] 有关,这里是以 AES256 来设定的; 第 2 3 段的公钥加密、私钥解密 都是使用 [非对称加密算法] ; 可能会有些其他缺陷... |
84
demonzoo 2019-08-27 20:26:28 +08:00
无法确保用户登录安全
|
86
abc612008 2019-08-27 21:00:01 +08:00
你可以说服所有主流操作系统 /浏览器嵌入你的公钥
|
87
well666 2019-08-27 21:05:27 +08:00 via iPhone
直接給你反代目標網站...啥都不幹就能全偷光
|
88
vinew 2019-08-27 21:34:19 +08:00 via iPhone
取消固定口令,通过邮箱发送随机密码
|
89
wwbfred 2019-08-27 22:01:11 +08:00
你的要求就是在不可信信道上进行可信通信.本质上与 https 的目的完全相同.所以模拟 https 就是现阶段最优方案.
否则你就可以发论文,论证你的方案优于 https,并且可以用于 https 的改进了. |
92
starsriver 2019-08-27 22:30:20 +08:00 via Android
每次登录都维持一个 socket 通信。
算了吧浪费资源。。 |
93
1521815837 2019-08-27 23:37:19 +08:00
session 一次性
|
94
mywaiting 2019-08-28 00:35:10 +08:00
我觉得楼上都没有讨论到点上
单纯网页的话,没有 https 的话,我随意各位各种折腾什么 md5,什么 rsa, 什么一次性密钥 你这些什么鬼 md5、rsa、一次性密钥,抵挡得住我往你的网页返回数据里插一段 js 么 加密的理论体系里,密钥需要保密、可靠传送才能换来对不安全信道的加密传送,你要是密钥也通过不安全信道传送,我要是截获,通用的算法下(甚至不通用的算法),解密不会什么特别困难的事情。你看看 HTTPS 的协议用了多大的努力才把这些坑给填了 归根到底,概括来说,对于单独的个体之间,确定其信任是件不可能的事情 不服?不服你自己可以试试思维实验一下,你的一段信息如何能安全、保密、无改动送达对方 要知道!互联网上传送信息的还要开放的信道和陌生的对方! 开什么玩笑? 自己发明加密协议,不是无知无畏就是蠢得太严重了 |
95
whileFalse 2019-08-28 07:57:17 +08:00 via iPhone
https 的核心是在本地计算机中预置了可信的根证书,证书可以衍生子证书或用于信道加密。
lz 的算法本身可以起到保护明文及抗重放的效果,但 lz 没法保证浏览器端使用了该算法,因为算法由页面代码指定,页面代码可被中间人替换。 lz 的问题在于对于本地计算机来说没有什么是可信的。解决办法也很简单, 使用可信的预先下载的客户端,而不是浏览器页面,来进行登录。 |
96
dingwen07 2019-08-28 08:02:25 +08:00 via Android
可以利用量子纠缠进行密钥分发
|
97
jin5354 2019-08-28 08:09:12 +08:00
http = 不安全
即使是楼上说的重新发明一个类 https 应用层也是不行的,因为 https 的可靠性还需要浏览器和系统根证书支援,脱离了这些还不是想改啥改啥 |
98
h175h32 2019-08-28 08:19:30 +08:00
没什么用 前端传输的是明文。不管是 https 还是 http 都能伪造一个登陆界面收集密码。
|
99
wizardoz 2019-08-28 08:30:11 +08:00
没有 https 就上 https。
自己瞎弄没意义,当你搞的足够安全时,会发现自己重复发明了 https。 |
100
Soar360 2019-08-28 08:44:12 +08:00 via iPhone
客户端 rsa 公钥?
|