SpringSecurity 密码加密登录

发布时间:2024年01月11日

1.前端所需文件

import JSEncrypt from 'jsencrypt/bin/jsencrypt.min'

// 密钥对生成 http://web.chacuo.net/netrsakeypair

const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' +
  'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='

const privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' +
  '7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' +
  'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' +
  'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' +
  'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' +
  'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' +
  'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' +
  'UP8iWi1Qw0Y='

// 加密
export function encrypt(txt) {
  const encryptor = new JSEncrypt()
  encryptor.setPublicKey(publicKey) // 设置公钥
  return encryptor.encrypt(txt) // 对数据进行加密
}

// 解密
export function decrypt(txt) {
  const encryptor = new JSEncrypt()
  encryptor.setPrivateKey(privateKey) // 设置私钥
  return encryptor.decrypt(txt) // 对数据进行解密
}


  this.loginForm = {
        username: username === undefined ? this.loginForm.username : username,
        password: password === undefined ? this.loginForm.password : decrypt(password),
        rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
      };

2.后端所用工具类

package com.nriat.site.common.utils;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * RSA加密解密
 *
 * @author ruoyi
 **/
public class RsaUtils {
    // Rsa 私钥
    public static String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALRMc5+BuKvnySp5" +
            "0geS+tvGSS4Kfe6/Gurfbc4GTJoUeZPnnAbdcD2NvQ9PXrpTIMW4VuXBfJ2vyE4x" +
            "dM4U9PIsnHOZPqPDRqIlubnCqjuvV63THV5rvIwPsuadZvf+cnAk4HIF8g9FLNH5" +
            "Exn8lRrc/ZYqOzuFkc+yuWZj57SzAgMBAAECgYAWNai0iF1AR9Ae/Fyj9DYUpotT" +
            "MZWruDzPm/BBxcLf5A/J6Wjt648s9e3JGgTYPO83i+qgaMI6BnJNN4hk7m3xxg2o" +
            "1mooI3e6aef3xz3H5CYwerkur22hgQpO3XXX97y0NFx/ST8lg9I1zMh63+5dHfXJ" +
            "MHe5WG1+YU7gxlN1sQJBAOKgMuNoSR7Gk8ehxFWt+lM1Q0RkUhd+REVN2KsWEjaP" +
            "aaxYKU5FU6p0GrStGAcvbzUaYUvXelIyk+VnVtCyvjkCQQDLqwuXtl9Iw/vsbji9" +
            "o7cKUYSwmbye8Yr208qBXzebiLcY1s+PKqGyo9y/1tAxCYyyKjOv99FOC7bAHuiw" +
            "+cpLAkEAotDNPqvxvHaWPVpvH886hQVDKqOYhuBkVBY1j9TviNtH5FYCdwU/srpv" +
            "ZVbmaGMf1lr5g+9vJhbIQowXxyBjoQJAJSb/h15SRWDS7M8ydI2Pz0cNkHWK7eeb" +
            "9OivkSgAadPnqpVM6Y3aT08K7sfN1JQsYTfHk/r96GHEpYk940K9vwJBALttsP0T" +
            "l9wVKKG995ZPdxc7nSj1R9oAEPAOOGSamlFV/s7+TFBJdgOZVw4T5+GjGOY5/Rft" +
            "wJvc9/lWECKRV4g=";

    /**
     * 私钥解密
     *
     * @param text 待解密的文本
     * @return 解密后的文本
     */
    public static String decryptByPrivateKey(String text) throws Exception {
        return decryptByPrivateKey(privateKey, text);
    }

    /**
     * 公钥解密
     *
     * @param publicKeyString 公钥
     * @param text            待解密的信息
     * @return 解密后的文本
     */
    public static String decryptByPublicKey(String publicKeyString, String text) throws Exception {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        byte[] result = cipher.doFinal(Base64.decodeBase64(text));
        return new String(result);
    }

    /**
     * 私钥加密
     *
     * @param privateKeyString 私钥
     * @param text             待加密的信息
     * @return 加密后的文本
     */
    public static String encryptByPrivateKey(String privateKeyString, String text) throws Exception {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        byte[] result = cipher.doFinal(text.getBytes());
        return Base64.encodeBase64String(result);
    }

    /**
     * 私钥解密
     *
     * @param privateKeyString 私钥
     * @param text             待解密的文本
     * @return 解密后的文本
     */
    public static String decryptByPrivateKey(String privateKeyString, String text) throws Exception {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] result = cipher.doFinal(Base64.decodeBase64(text));
        return new String(result);
    }

    /**
     * 公钥加密
     *
     * @param publicKeyString 公钥
     * @param text            待加密的文本
     * @return 加密后的文本
     */
    public static String encryptByPublicKey(String publicKeyString, String text) throws Exception {
        X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] result = cipher.doFinal(text.getBytes());
        return Base64.encodeBase64String(result);
    }

    /**
     * 构建RSA密钥对
     *
     * @return 生成后的公私钥信息
     */
    public static RsaKeyPair generateKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(1024);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
        String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded());
        String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
        return new RsaKeyPair(publicKeyString, privateKeyString);
    }

    /**
     * RSA密钥对对象
     */
    public static class RsaKeyPair {
        private final String publicKey;
        private final String privateKey;

        public RsaKeyPair(String publicKey, String privateKey) {
            this.publicKey = publicKey;
            this.privateKey = privateKey;
        }

        public String getPublicKey() {
            return publicKey;
        }

        public String getPrivateKey() {
            return privateKey;
        }
    }
}


3.登录代码

  public TokenVo login(String username, String password) {
        try {
            password=RsaUtils.decryptByPrivateKey(password);
        }catch (Exception e) {
            log.error("Failed to decrypt password: {}", e.getMessage());
            throw new CustomException(ResultCodeEnum.LOGIN_DECRYPT_ERROR);
        }
        //封装 Authentication
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
        //认证用户
        Authentication authenticate;
        try {
            authenticate = authenticationManager.authenticate(authenticationToken);
        } catch (Exception e) {
            log.error("Authentication failed: {}", e.getMessage());
            throw new CustomException(ResultCodeEnum.LOGIN_AUTH_ERROR);
        }
        //获取认证用户信息
        UserDetailsInfo userDetailsInfo = (UserDetailsInfo) authenticate.getPrincipal();
        boolean matches = passwordEncoder.matches(password, userDetailsInfo.getPassword());
        if (!matches) {
            throw new CustomException(ResultCodeEnum.LOGIN_PWD_ERROR);
        }
        //认证通过,生成jwt
        TokenVo tokenVo=new TokenVo();
        String token = jwtTokenUtil.generateToken(userDetailsInfo);
        tokenVo.setToken(token);
        tokenVo.setExpireTime(jwtTokenUtil.expiration);
        redisCache.setCacheObject(RedisConst.REDIS_TOKEN_PREFIX+token, userDetailsInfo, jwtTokenUtil.expiration, TimeUnit.SECONDS);

        return tokenVo;
    }

4.灵魂一问

passwordEncoder.matches(“A”, “B”); ,如果返还是True,这个B其实就是A通过passwordEncoder.encode();加密的对吧?

不完全正确。在Spring Security中,passwordEncoder.matches(“A”, “B”)的返回值为true表示密码匹配成功,即明文密码"A"与加密后的密码"B"是匹配的。

passwordEncoder.encode(“A”)会将明文密码"A"进行加密,生成一个新的加密密码。每次调用passwordEncoder.encode(“A”)都会生成不同的加密密码,即使输入的明文密码相同。

因此,如果passwordEncoder.matches(“A”, “B”)返回true,并不意味着"B"是由"A"通过passwordEncoder.encode()加密得到的。它只表示明文密码"A"与加密密码"B"是匹配的,即密码验证成功。

文章来源:https://blog.csdn.net/qq_46058550/article/details/135526840
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。