浏览器和Spring MVC后端之间加密和解密密码

问题描述 投票:0回答:1

我想在浏览器和 Spring MVC 后端之间安全地传输和处理用户密码。密码在客户端加密,在服务器端解密后再验证

前端代码:

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>

<script>
  function encryptPassword(password) {
    const encryptedPassword = CryptoJS.AES.encrypt(password, "SecretKey123").toString();
    return encryptedPassword;
  }

  document.getElementById("loginForm").onsubmit = function (e) {
    e.preventDefault();
    const passwordField = document.getElementById("password");
    passwordField.value = encryptPassword(passwordField.value);
    this.submit();
  };
</script>

<form id="loginForm" method="POST" action="/login">
  <input type="text" name="username" required />
  <input type="password" id="password" name="password" required />
  <button type="submit">Login</button>
</form>

后端代码:

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

@Controller
@RequestMapping("/login")
public class LoginController {
    private static final String SECRET_KEY = "SecretKey123"; // Must be 16 chars for AES

    @PostMapping
    public String login(@RequestParam String username, @RequestParam String password, Model model) {
        try {
            String decryptedPassword = decrypt(password);
            // Validate username and decryptedPassword
            // Perform authentication logic
        } catch (Exception e) {
            model.addAttribute("error", "Invalid encryption");
            return "login";
        }
        return "home";
    }

    private String decrypt(String encryptedPassword) throws Exception {
        SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decodedBytes = Base64.getDecoder().decode(encryptedPassword);
        byte[] original = cipher.doFinal(decodedBytes);
        return new String(original);
    }
}

我不确定我的实现是否安全,或者在此用例中是否有更好的加密和解密实践。

java spring-mvc passwords password-encryption
1个回答
0
投票

就像@luk2302评论的那样,你应该仔细思考为什么要这样做。

在大多数情况下,依靠 HTTPS 提供的安全性就足够了。它使您的应用程序保持简单并提供高级别的安全性。 服务器端需要注意的一些事项:

  • 不要通过 HTTP 提供应用程序流量 - 它应该全部重定向到 HTTPS。
  • 使用 HSTS 确保浏览器强制使用 HTTPS。
  • 不要以明文或加密方式存储用户密码,对密码进行哈希处理并比较哈希值。

如果您预计风险更大,例如用户更容易受到社会工程攻击,您应该实施额外的保护层,从而显着增加 MitM 攻击的复杂性。如果用户安装恶意证书并通过恶意代理发送流量,攻击者就可以通过 MitM 攻击窃取用户的凭据。在这种情况下,可能需要实施额外的加密。

对于这种情况,协商安全密钥交换过程并通过 HTTPS 使用公钥加密应该可以解决您的需求。您可以研究ECDH以获取更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.