spring security 安全策略加密解密处理过程

1.现在后台生成密钥对,把得到公钥的加密系数,加密指数,传个前台登录界面,进行加密

//rsa生成密钥对,和加密解密函数。

public class RSAUtil
{
  private static String RSAKeyStore = "RSAKey.txt"

  public static KeyPair generateKeyPair()
    throws Exception
  {
    try
    {
      KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", 
        new BouncyCastleProvider());
      int KEY_SIZE = 1024;
      keyPairGen.initialize(1024, new SecureRandom());
      KeyPair keyPair = keyPairGen.generateKeyPair();

      System.out.println(keyPair.getPrivate().toString().length());
      System.out.println(keyPair.getPublic());

      saveKeyPair(keyPair);
      return keyPair;
    } catch (Exception e) {
      throw new Exception(e.getMessage());
    }
  }

  public static KeyPair getKeyPair() throws Exception {
    FileInputStream fis = new FileInputStream(Constants_core.ContextRealPath + File.separator + RSAKeyStore);
    ObjectInputStream oos = new ObjectInputStream(fis);
    KeyPair kp = (KeyPair)oos.readObject();
    oos.close();
    fis.close();
    return kp;
  }

  public static void saveKeyPair(KeyPair kp) throws Exception
  {
    FileOutputStream fos = new FileOutputStream(Constants_core.ContextRealPath + File.separator + RSAKeyStore);
    ObjectOutputStream oos = new ObjectOutputStream(fos);

    oos.writeObject(kp);
    oos.close();
    fos.close();
  }

  public static RSAPublicKey generateRSAPublicKey(byte[] modulus, byte[] publicExponent)
    throws Exception
  {
    KeyFactory keyFac = null;
    try {
      keyFac = KeyFactory.getInstance("RSA", 
        new BouncyCastleProvider());
    } catch (NoSuchAlgorithmException ex) {
      throw new Exception(ex.getMessage());
    }

    RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
      new BigInteger(modulus), new BigInteger(publicExponent));
    try {
      return (RSAPublicKey)keyFac.generatePublic(pubKeySpec);
    } catch (InvalidKeySpecException ex) {
      throw new Exception(ex.getMessage());
    }
  }

  public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus, byte[] privateExponent)
    throws Exception
  {
    KeyFactory keyFac = null;
    try {
      keyFac = KeyFactory.getInstance("RSA", 
        new BouncyCastleProvider());
    } catch (NoSuchAlgorithmException ex) {
      throw new Exception(ex.getMessage());
    }

    RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(
      new BigInteger(modulus), new BigInteger(privateExponent));
    try {
      return (RSAPrivateKey)keyFac.generatePrivate(priKeySpec);
    } catch (InvalidKeySpecException ex) {
      throw new Exception(ex.getMessage());
    }
  }

  public static byte[] encrypt(PublicKey pk, byte[] data)
    throws Exception
  {
    try
    {
      Cipher cipher = Cipher.getInstance("RSA", 
        new BouncyCastleProvider());
      cipher.init(1, pk);
      int blockSize = cipher.getBlockSize();

      int outputSize = cipher.getOutputSize(data.length);
      int leavedSize = data.length % blockSize;
      int blocksSize = (leavedSize != 0) ? data.length / blockSize + 1 : 
        data.length / blockSize;
      byte[] raw = new byte[outputSize * blocksSize];
      int i = 0;
      while (data.length - i * blockSize > 0) {
        if (data.length - i * blockSize > blockSize)
          cipher.doFinal(data, i * blockSize, blockSize, raw, i * 
            outputSize);
        else {
          cipher.doFinal(data, i * blockSize, data.length - i * 
            blockSize, raw, i * outputSize);
        }

        ++i;
      }
      return raw;
    } catch (Exception e) {
      throw new Exception(e.getMessage());
    }
  }

  public static byte[] decrypt(PrivateKey pk, byte[] raw)
    throws Exception
  {
    try
    {
      Cipher cipher = Cipher.getInstance("RSA", 
        new BouncyCastleProvider());
      cipher.init(2, pk);
      int blockSize = cipher.getBlockSize();
      ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
      int j = 0;

      while (raw.length - j * blockSize > 0) {
        bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
        ++j;
      }
      return bout.toByteArray();
    } catch (Exception e) {
      throw new Exception(e.getMessage());
    }
  }

  public static String decrypt(PrivateKey pk, String str_en)
    throws Exception
  {
    String str_mw = "";
    byte[] en_result = new BigInteger(str_en, 16).toByteArray();
    byte[] de_result = decrypt(getKeyPair().getPrivate(), en_result);
    StringBuffer sb = new StringBuffer();
    sb.append(new String(de_result));
    str_mw = sb.reverse().toString();
    str_mw = URLDecoder.decode(str_mw, "UTF-8");
    return str_mw;
  }

  public static void main(String[] args)
    throws Exception
  {
    Constants_core.ContextRealPath = "D:/EPS/ygpt/WebRoot";
    String test = "hello world";
    byte[] en_test = encrypt(getKeyPair().getPublic(), test.getBytes());
    String stren = Base64.encode(en_test);
    byte[] de_test = decrypt(getKeyPair().getPrivate(), Base64.decode(stren));
    System.out.println(new String(de_test));
  }
}
//前台js加密

 var j_password = document.getElementById("j_password_show").value;
    	  document.getElementById("j_password").value = encryptedString(key, encodeURIComponent(j_password));
    	 
        LOGIN_FORM.submit();

2.点击登录时,密码被用rsa加密后发到spring security的 DaoAuthenticationProvider 进行密码校验处理,

在密码发到后台后,先用在第一步时产生的私钥进行解密,解密后再用spring security 提供的 passwordEncoder类的

this.passwordEncoder.isPasswordValid()方法来进行,密码校验。


public DaoAuthenticationProvider()
  {
    setPasswordEncoder(new PlaintextPasswordEncoder());
  }

  protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication)
    throws AuthenticationException
  {
    Object salt = null;

    if (this.saltSource != null) {
      salt = this.saltSource.getSalt(userDetails);
    }

    if (authentication.getCredentials() == null) {
      this.logger.debug("Authentication failed: no credentials provided");

      throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"), userDetails);
    }
	//rsa私钥解密
	try {
				presentedPassword = RSAUtil.decrypt(RSAUtil.getKeyPair().getPrivate(),presentedPassword);
			} catch (Exception e) {
				this.logger.error(e, e.fillInStackTrace());
			}

    String presentedPassword = authentication.getCredentials().toString();
	//校验密码
    if (!this.passwordEncoder.isPasswordValid(userDetails.getPassword(), presentedPassword, salt)) {
      this.logger.debug("Authentication failed: password does not match stored value");

      throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"), userDetails);
    }
  }

  protected void doAfterPropertiesSet() throws Exception
  {
    Assert.notNull(this.userDetailsService, "A UserDetailsService must be set");
  }

  protected final UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException
  {
    UserDetails loadedUser;
    try
    {
      loadedUser = getUserDetailsService().loadUserByUsername(username);
    } catch (UsernameNotFoundException notFound) {
      if (authentication.getCredentials() != null) {
        String presentedPassword = authentication.getCredentials().toString();
        this.passwordEncoder.isPasswordValid(this.userNotFoundEncodedPassword, presentedPassword, null);
      }
      throw notFound;
    } catch (Exception repositoryProblem) {
      throw new AuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem);
    }

    if (loadedUser == null) {
      throw new AuthenticationServiceException("UserDetailsService returned null, which is an interface contract violation");
    }

    return loadedUser;
  }

  public void setPasswordEncoder(Object passwordEncoder)
  {
    Assert.notNull(passwordEncoder, "passwordEncoder cannot be null");

    if (passwordEncoder instanceof org.springframework.security.authentication.encoding.PasswordEncoder) {
      setPasswordEncoder((org.springframework.security.authentication.encoding.PasswordEncoder)passwordEncoder);
      return;
    }

    if (passwordEncoder instanceof org.springframework.security.crypto.password.PasswordEncoder) {
      org.springframework.security.crypto.password.PasswordEncoder delegate = (org.springframework.security.crypto.password.PasswordEncoder)passwordEncoder;

      setPasswordEncoder(new org.springframework.security.authentication.encoding.PasswordEncoder(delegate) {
        public String encodePassword(String rawPass, Object salt) {
          checkSalt(salt);
          return this.val$delegate.encode(rawPass);
        }

        public boolean isPasswordValid(String encPass, String rawPass, Object salt) {
          checkSalt(salt);
          return this.val$delegate.matches(rawPass, encPass);
        }

        private void checkSalt(Object salt) {
          Assert.isNull(salt, "Salt value must be null when used with crypto module PasswordEncoder");
        }
      });
      return;
    }

    throw new IllegalArgumentException("passwordEncoder must be a PasswordEncoder instance");
  }

  private void setPasswordEncoder(org.springframework.security.authentication.encoding.PasswordEncoder passwordEncoder) {
    Assert.notNull(passwordEncoder, "passwordEncoder cannot be null");

    this.userNotFoundEncodedPassword = passwordEncoder.encodePassword("userNotFoundPassword", null);
    this.passwordEncoder = passwordEncoder;
  }

  protected org.springframework.security.authentication.encoding.PasswordEncoder getPasswordEncoder() {
    return this.passwordEncoder;
  }

  public void setSaltSource(SaltSource saltSource)
  {
    this.saltSource = saltSource;
  }

  protected SaltSource getSaltSource() {
    return this.saltSource;
  }

  public void setUserDetailsService(UserDetailsService userDetailsService) {
    this.userDetailsService = userDetailsService;
  }

  protected UserDetailsService getUserDetailsService() {
    return this.userDetailsService;
  }
}

3.为什么这么做呢,因为,后台数据库存储的密码都是经过不可逆算法加密过的,用这个方法,对3第三部解密后的密码在进行加密处理,最后和数据存储的加密密码进行比较,返回true则密码通过验证。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值