DBILITY

PropertyPlaceholder에 ARIA Crypto 적용하기 본문

java/spring

PropertyPlaceholder에 ARIA Crypto 적용하기

DBILITY 2017. 9. 7. 11:43
반응형

현재 프로젝트에서 사용하는 스프링 버전은 3.1.1로 db접속 정보 등을 property파일에 jasypt를 이용해 암호화를 적용하고 있는데,

전자정부 프레임워크의 ARIA블록 암호화를 적용해 보기 위해 jasypt package의 EncryptablePropertyPlaceholderConfigurer를 참고하여

PropertyPlaceholderConfigurer를 상속받아 property를 복호화하도록 보고 베꼈다.

URLEncoder/URLDecoder는 필요하지 않을 경우 제거해도 된다.

전자정부 프레임워크에는 아마도 이미 있지 않을까? 사용해 보지 않아 모르겠다.

 

  1. EgovStringToHashEncryptor에서 사용할 패스워드 생성용 RandomKeyGenerator

    package com.dbility.apps.cmm.enc.generator;
     
    import java.util.Random;
     
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
     
    /**
     *
     * Description
     *
     *
     * @author hyperrookie@gmail.com
     *
     * @version 1.0.0
     * @date 2014. 7. 27.
     *=======================================================================
     * Date             Name                                Revision History
     *=======================================================================
     * 2014. 7. 27.     hyperrookie@gmail.com               Creation
     *=======================================================================
     */
    public class RandomKeyGenerator {
     
        private static final Logger logger = LoggerFactory.getLogger(RandomKeyGenerator.class);
        private static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ!@^=";
        private static final int LEN = 40;
        private static Random rnd = new Random();
     
        public static void main(String[] args) {
     
            StringBuilder sb = new StringBuilder(LEN);
            for (int i = 0; i < LEN; i++)
                sb.append(AB.charAt(rnd.nextInt(AB.length())));
     
            logger.info(sb.toString());
     
        }
     
    }​


  2. EgovPasswordEncoder에서 사용할 HashedPassword생성용 EgovStringToHashEncryptor
    package com.dbility.apps.cmm.enc.generator;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import com.dbility.apps.cmm.enc.EgovPasswordEncoder;
    
    /**
     * 
     * Description
     * 
     * 
     * @author hyperrookie@gmail.com
     * 
     * @version 1.0.0
     * @date 2017. 9. 6.
     *=======================================================================
     * Date				Name								Revision History
     *=======================================================================
     * 2017. 9. 6.		hyperrookie@gmail.com				Creation
     *=======================================================================
     */
    public class EgovStringToHashEncryptor {
    
    	private static final Logger logger = LoggerFactory.getLogger(EgovStringToHashEncryptor.class);
    		
    		public static void main(String[] args) {
    			
    			String algorism = "SHA-256";
    			String password = "EW^N3O1WC@@7JMF=442@75AOT@374IVJTZ!3Z@36";
    			
    			EgovPasswordEncoder encoder = new EgovPasswordEncoder();
    
    			encoder.setAlgorithm(algorism);
    			
    			String hashPassword 	= encoder.encryptPassword(password);
    
    			logger.debug("hashPassword : {}", hashPassword);
    		}
    
    }
  3. Property파일에 사용할 정보 암호화 EgovAriaStringEncryptor
    package com.dbility.apps.cmm.enc.generator;
    
    import java.io.UnsupportedEncodingException;
    import java.net.URLDecoder;
    import java.net.URLEncoder;
    
    import org.apache.commons.codec.binary.Base64;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import com.dbility.apps.cmm.enc.EgovARIACryptoService;
    import com.dbility.apps.cmm.enc.EgovPasswordEncoder;
    import com.dbility.apps.cmm.enc.impl.EgovARIACryptoServiceImpl;
    
    /**
     * 
     * Description
     * 
     * 
     * @author hyperrookie@gmail.com
     * 
     * @version 1.0.0
     * @date 2017. 9. 6.
     *=======================================================================
     * Date				Name								Revision History
     *=======================================================================
     * 2017. 9. 6.		hyperrookie@gmail.com				Creation
     *=======================================================================
     */
    public class EgovAriaStringEncryptor {
    	
    	private static final Logger logger = LoggerFactory.getLogger(EgovAriaStringEncryptor.class);
    	private static final String masterKey = "EW^N3O1WC@@7JMF=442@75AOT@374IVJTZ!3Z@36"; // aria password
    	
    	private static EgovARIACryptoService encryptor = new EgovARIACryptoServiceImpl();
    		
    	
    	public static void main(String[] args) throws UnsupportedEncodingException {
    						
    		EgovPasswordEncoder passwordEncoder = new EgovPasswordEncoder();
    		passwordEncoder.setAlgorithm("SHA-256");
    		passwordEncoder.setHashedPassword("hi14YIoN9das2MbSh5ENmfCW6iTN2l59kWHPs/7/sAA=");
    		
    		encryptor.setBlockSize(1025);
    		encryptor.setPasswordEncoder(passwordEncoder);	
    		
    		String driver 	= EgovAriaStringEncryptor.encode("oracle.jdbc.OracleDriver");
    		String url 		= EgovAriaStringEncryptor.encode("jdbc:oracle:thin:@localhost:1521:ORCL");
    		String username = EgovAriaStringEncryptor.encode("scott");
    		String password = EgovAriaStringEncryptor.encode("tiger");
    		String jndi 	= EgovAriaStringEncryptor.encode("dev");
    		
    		logger.debug("driver : {}", driver);
    		logger.debug("url : {}", url);
    		logger.debug("username : {}", username);
    		logger.debug("password : {}", password);
    		logger.debug("jndi.name : {}", jndi);
    		
    		logger.debug("driver(dec) : {}", EgovAriaStringEncryptor.decode(driver));
    		logger.debug("url(dec) : {}", 	 EgovAriaStringEncryptor.decode(url));
    		logger.debug("username(dec) : {}", EgovAriaStringEncryptor.decode(username));
    		logger.debug("password(dec) : {}", EgovAriaStringEncryptor.decode(password));
    		logger.debug("jndi.name(dec) : {}", EgovAriaStringEncryptor.decode(jndi));	
    
    	}
    	
    	public static String encode(String plainText) throws UnsupportedEncodingException {		
    		return URLEncoder.encode(Base64.encodeBase64String(encryptor.encrypt(plainText.getBytes("UTF-8"), masterKey)),"UTF-8");
    	}
    	
    	public static String decode(String encodeText) throws UnsupportedEncodingException {		
    		return new String(encryptor.decrypt(Base64.decodeBase64(URLDecoder.decode(encodeText,"UTF-8")), masterKey));
    	}
    
    }
  4. db.peroperies.xml
    <!--?xml version="1.0" encoding="UTF-8"?-->
    <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd" >
    <properties>
        <entry key="oracle.jdbc.driver">ENC(bejr9KQmj9MYoXFBOgvvtWauop5iE7aOOLd0FjRyV%2BE%3D)</entry>
        <entry key="oracle.jdbc.url">ENC(XlGYiRRg9jvWehCrp99HwTG9qj7eBOlakGpRUP%2F39aWANEqQpn1Ewri%2Bm%2FieGOWs)</entry>   
        <entry key="oracle.jdbc.username">ENC(kc0sHVbtOmThy89eH%2BNXlQ%3D%3D)</entry>
        <entry key="oracle.jdbc.password">ENC(cI6du5suQ3C7VzbshR9fLQ%3D%3D)</entry>
    </properties>
  5. EncryptablePropertyPlaceholderConfigurer
    package com.dbility.apps.cmm.config;
    
    import java.net.URLDecoder;
    
    import org.apache.commons.codec.binary.Base64;
    import org.springframework.beans.factory.annotation.Required;
    import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
    
    import com.dbility.apps.cmm.enc.EgovARIACryptoService;
    
    /**
     * 
     * Description
     * 
     * 
     * @author hyperrookie@gmail.com
     * 
     * @version 1.0.0
     * @date 2017. 9. 6.
     *=======================================================================
     * Date				Name								Revision History
     *=======================================================================
     * 2017. 9. 6.		hyperrookie@gmail.com				Creation
     *=======================================================================
     */
    public class EncryptablePropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
    	
    	//private static final Logger logger = LoggerFactory.getLogger(EncryptablePropertyPlaceholderConfigurer.class);	
    	private static final String ENCRYPTED_VALUE_PREFIX = "ENC(";
    	private static final String ENCRYPTED_VALUE_SUFFIX = ")";
        
    	private final EgovARIACryptoService encryptor;	
    	private String password;
    	
    	@Required
    	public void setPassword(String password) {
    		
    		this.password = password;
    	}
    
    	public EncryptablePropertyPlaceholderConfigurer(EgovARIACryptoService encryptor) {
    		super();
    						
    		if ( encryptor  == null) {
                throw new IllegalArgumentException("Encryptor cannot be null");
            }
    		
    		this.encryptor = encryptor;
    	}
    	
    	@Override
    	protected String convertPropertyValue(String originalValue) {		
    		if (!EncryptablePropertyPlaceholderConfigurer.isEncryptedValue(originalValue)) {
    			return originalValue;
    		}
    		return new String(this.encryptor.decrypt(Base64.decodeBase64(URLDecoder.decode(EncryptablePropertyPlaceholderConfigurer.getInnerEncryptedValue(originalValue)),"UTF-8"), this.password));
    	}
    	
    	private static boolean isEncryptedValue(final String value) {
            if (value == null) {
                return false;
            }
            final String trimmedValue = value.trim();
            return (trimmedValue.startsWith(ENCRYPTED_VALUE_PREFIX) && 
                    trimmedValue.endsWith(ENCRYPTED_VALUE_SUFFIX));
        }
        
        private static String getInnerEncryptedValue(final String value) {
            return value.substring(
                    ENCRYPTED_VALUE_PREFIX.length(),
                    (value.length() - ENCRYPTED_VALUE_SUFFIX.length()));
        }
    }
  6. DataSource 적용
    <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
        <property name="driverClassName" value="${oracle.jdbc.driver}" />
        <property name="url" value="${oracle.jdbc.url}" />
        <property name="username" value="${oracle.jdbc.username}" />
        <property name="password" value="${oracle.jdbc.password}" />
        <property name="defaultAutoCommit" value="true" />
        <property name="initialSize" value="5" />
        <property name="minIdle" value="5" />
        <property name="maxIdle" value="5" />
        <property name="maxActive" value="10" />
        <property name="testOnConnect" value="true" />
        <property name="validationQuery" value="select sysdate from dual" />
    </bean>
  7. PropertyPlaceholder적용
    <!-- jaspty 3.1 -->
        <!-- <bean id="environmentVariablesConfiguration" class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
            <property name="algorithm" value="PBEWithMD5AndDES" />
            <property name="passwordEnvName" value="APP_ENCRYPTION_PASSWORD"/>
        </bean>
        <bean id="configurationEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
            <property name="config" ref="environmentVariablesConfiguration"/>
            <property name="password" value="4M1HK3I@8RD2K!FQI6YNZJAQ3DRE7I9JEJC7PYMV"/>   
        </bean>
        <bean id="propertyConfigurer" class="org.jasypt.spring31.properties.EncryptablePropertyPlaceholderConfigurer">
            <constructor-arg ref="configurationEncryptor"/>
            <property name="locations">
                <list>
                    <value>classpath:property/db.properties.xml</value>        
                </list>
            </property>
        </bean> -->
         
        <bean id="passwordEncoder" class="com.dbility.apps.cmm.enc.EgovPasswordEncoder">
          <property name="algorithm" value="SHA-256" /><!-- default : SHA-256 -->
          <property name="hashedPassword" value="hi14YIoN9das2MbSh5ENmfCW6iTN2l59kWHPs/7/sAA=" />
        </bean>
          
        <bean id="ARIACryptoService" class="com.dbility.apps.cmm.enc.impl.EgovARIACryptoServiceImpl">
          <property name="passwordEncoder" ref="passwordEncoder" />
          <property name="blockSize" value="1025" /><!-- default : 1024 -->
        </bean>
     
        <bean id="propertyConfigurer" class="com.dbility.apps.cmm.config.EncryptablePropertyPlaceholderConfigurer">
            <constructor-arg ref="ARIACryptoService" />      
            <property name="password" value="EW^N3O1WC@@7JMF=442@75AOT@374IVJTZ!3Z@36" />
            <property name="locations">
                <list>
                    <value>classpath:property/db.properties.xml</value>        
                </list>
            </property>
        </bean>

 

반응형
Comments