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));
- }
- }
- 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则密码通过验证。