网站登录,如何避免明文传输用户登录密码?

网站登录,如何避免明文传输用户登录密码?

对于系统登录页面来说,我们作为开发人员,应该没有陌生的吧。就像下面这样子。

点击登录,调用/login 接口。来看下面截图中的 载荷(payload)数据,其中,密码 password 的值是明文。

如果你的站点使用的是HTTPS协议,配置了有效的SSL证书,那将很好。HTTPS通过SSL/TLS协议建立安全的加密通信通道,确保传输过程中的数据被加密。这样,用户在登录页面输入的密码将在传输过程中得到保护。

如果你的站点使用的是普通的HTTP协议,安全层面,就要考虑了。因为,HTTP会使用明文的形式将这个用户密码提交到服务端接口。

因此,前后端需要改造一下,使用密文来传输用户密码。

AI告诉我们,如果需要在客户端对密码进行加密,可以使用JavaScript等技术对密码进行加密处理,然后再将加密后的密码传输给服务器。这样即使在传输过程中,密码也是以加密形式传输的。但是要注意,客户端加密需要谨慎设计和实施,确保密码的加密过程安全可靠。

就像下面这样子。

如何实现?

我们的系统是基于ruoyi框架搭建的。

前端jquery引入CryptoJS库,利用DES加密算法对密码进行加密。

问题来了,加密key怎么办?

一种方案,是前端调用服务端接口获取动态加密key。这是常规的办法。

现在,我们使用另一种方案,不需要调用后端接口获取key的办法。

前端如何生成动态key,而且还能让后端接口能解密?

答案是:基于时间。再细节一些,基于当前时间戳。

你一定会存疑:用户浏览器和服务器时间不一定总是一致呀!

是的。因此,先省略一些文字,直接贴代码给你看吧。

1 function login() {

2 var username = $.common.trim($("input[name='username']").val());

3 var password = $.common.trim($("input[name='password']").val());

4 var validateCode = $("input[name='validateCode']").val();

5 var rememberMe = $("input[name='rememberme']").is(':checked');

6 var key = Math.floor(jQuery.now() / 30000).toString();

7 $.ajax({

8 type: "post",

9 url: ctx + "login",

10 data: {

11 "username": username,

12 "password": encryptByDES(password, key),

13 "validateCode" : validateCode,

14 "rememberMe": rememberMe

15 },

16 success: function(r) {

17 if (r.code == 0) {

18 location.href = ctx + 'index';

19 } else {

20 ...

21 }

22 }

23 });

24 }

25

26 function encryptByDES(message,key) {

27 var keyHex = CryptoJS.enc.Utf8.parse(key);

28 console.log("keyHex:"+keyHex)

29 var encrypted = CryptoJS.DES.encrypt(message, keyHex, {

30 mode: CryptoJS.mode.ECB,

31 padding: CryptoJS.pad.Pkcs7

32 });

33 return encrypted.toString();

34 }

View Code

重点是第6行。jQuery.now() 是 jQuery库 提供的一个方法,通过依赖调用JavaScript原生的new Date().getTime(),来更高效地获取当前的时间戳,即:自 Unix 纪元(1970年1月1日 00:00:00 UTC)以来的毫秒数。

明白后,我们再看后端程序对密文的处理。

// *password 是前端传过来的密文

long floor = (long) Math.floor(System.currentTimeMillis() / 30000);

String passwordText = null; // *明文

try {

passwordText = DESUtils.decrypt(password, String.valueOf(floor));

} catch (Exception e) {

log.error("密码解密异常1:", e);

try {

passwordText = DESUtils.decrypt(password, String.valueOf(floor-1));

} catch (Exception ex) {

log.error("密码解密异常2:", e);

return error("非法请求");

}

}

View Code

看完代码,你是否GET到其中对密码加密的技能?

OK,让我来解锁一下这个技能策略。在双因子登录的技术里,有一种基于时间生成动态码的开源算法TOTP。这个算法会考虑预留给用户足够的操作时间。它生成时间的算法是 T = floor(currentTimestamp / step)。其中,currentTimestamp 为当前的时间戳,单位为秒,step 为步长,在用户登录的场景一般是 30s ,floor 为向下取整。通过这样计算出来的 T 值,在一定时长内会保持一致(比如 00:00 ~ 00:29 为 1,00:30 ~ 00:59 为 2),每 30 秒便会自增。

上面加密策略里,也是借鉴了上面TOTP算法的思想,前后端基于一个短时间内不变的时间T值,作为加密因子,通过DES算法对用户密码进行加解密,巧妙地避免了用户密码在网络上的明文传输。

关于用户登录密码的安全,上面用的是DES这种简单的加密算法。其实,如果想更安全,可以使用非对称加密算法,如RSA。下图短视频里的WEB浏览器网络请求,展示了用户在每次提交登录时,前端调用服务端接口获取RSA公钥,然后对用户密码加密传输,服务端依据自己存储的RSA私钥解密得到实际的用户密码。

【后记】本文的安全控制方案,有一个缺陷,是服务端可以得到用户的实际密码,这在信息安全方面,是不合格的。因为用户密码属于用户隐私数据,理应只有用户本人知道,其他任何人、以及所在网站系统都无权知道。关于登录安全的进阶,戳系统网站登录,如何合规传输用户登录密码?

🖌️ 相关文章

宜信财富理财顾问面试经验
365bet足球网投

宜信财富理财顾问面试经验

📅 09-11 👁️ 658
csgo反恐精英录像radio是哪个键
Bet体育365提款要多久2022

csgo反恐精英录像radio是哪个键

📅 08-09 👁️ 9632
《輞川集》
Bet体育365提款要多久2022

《輞川集》

📅 07-08 👁️ 8980