package it.geosolutions.geostore.core.security.password; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; import org.springframework.dao.DataAccessException; import org.springframework.security.authentication.encoding.PasswordEncoder; /** * This class wraps the old password encoding and decoding system * @author Lorenzo Natali (lorenzo.natali at geo-solutions.it) * */ public class GeoStoreAESEncoder extends AbstractGeoStorePasswordEncoder { private static final byte[] DEFALULT_KEY = "installation dependant key needed".substring(0, 16).getBytes(); private byte[] key = GeoStoreAESEncoder.DEFALULT_KEY; public void setKey(String key) { this.key = key.substring(0, 16).getBytes(); } @Override protected PasswordEncoder createStringEncoder() { // TODO Auto-generated method stub return null; } @Override protected CharArrayPasswordEncoder createCharEncoder() { // TODO Auto-generated method stub return null; } @Override public PasswordEncodingType getEncodingType() { return PasswordEncodingType.GEOSTORE; } @Override public boolean isPasswordValid(String encPass, String rawPass, Object salt) throws DataAccessException { if (encPass==null) return false; return rawPass.equals(decode(encPass)); } @Override public String encodePassword(char[] rawPass, Object salt) throws DataAccessException { try { SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, keySpec); byte[] b = new byte[rawPass.length]; for (int i = 0; i < b.length; i++) { b[i] = (byte) rawPass[i]; } byte[] input = b; byte[] encrypted = cipher.doFinal(input); byte[] output = Base64.encodeBase64(encrypted); return new String(output); } catch (NoSuchAlgorithmException ex) { throw new RuntimeException("Error while encoding", ex); } catch (NoSuchPaddingException ex) { throw new RuntimeException("Error while encoding", ex); } catch (IllegalBlockSizeException ex) { throw new RuntimeException("Error while encoding", ex); } catch (BadPaddingException ex) { throw new RuntimeException("Error while encoding", ex); } catch (InvalidKeyException ex) { throw new RuntimeException("Error while encoding", ex); } } @Override public String decode(String encPass) throws UnsupportedOperationException { try { SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, keySpec); byte[] de64 = Base64.decodeBase64(encPass); byte[] decrypted = cipher.doFinal(de64); return new String(decrypted); } catch (NoSuchAlgorithmException ex) { throw new RuntimeException("Error while encoding", ex); } catch (NoSuchPaddingException ex) { throw new RuntimeException("Error while encoding", ex); } catch (IllegalBlockSizeException ex) { throw new RuntimeException("Error while encoding", ex); } catch (BadPaddingException ex) { throw new RuntimeException("Error while encoding", ex); } catch (InvalidKeyException ex) { throw new RuntimeException("Error while encoding", ex); } } @Override public boolean isResponsibleForEncoding(String encPass) { if(encPass == null ) return false; String[] split = encPass.split(GeoStorePasswordEncoder.PREFIX_DELIMTER); if(split.length == 0) return true; //TODO get these strings in a better way String prefix = split[0]; return !(prefix.equals("crypt1") || prefix.equals("crypt2") || prefix.equals("digest1") || prefix.equals("empty") || prefix.equals("plain")); } }