为什么加解密?
主要是防止别人偷看和篡改。
实现方式?
1. 使用filter来监听文件,统一处理配置文件(最好、麻烦)
2. 在spring读取时和使用工具第一次读取配置文件时来加密文件,以后每次读取解密。(简单、只好加密,不好解密修改)
3.使用mvn的替换工具将配置文件中的变量在编译时被替换。(无脑的使用maven插件,配置文件还是没有加密)
4.将一些密码之类的东西加密,比较麻烦。
第二种方式的实现
1. 在spring使用的时候读取加密整个配置文件。 2. 加密后在行首插入特殊字符,标识文件被加密。 3. 在spring使用的时候解密配置文件,然后每次解密即可。 复写spring的配置文件读取类来实现: public class EncryptPropertyPlaceHolderConfigurer extends PropertyPlaceholderConfigurer {
/** 文件加密字符串. */ private static final String ENCRYPT_STRING ="afobhaobfoasbfoasbfoabfbfflasbf";
/** 标记文件加密的首行内容. */ private static final String CHECK_STRING ="#**#";
private Resource[]locations;
private StringfileEncoding;
private PropertiesPersisterpropertiesPersister = new DefaultPropertiesPersister();
public static final String LINE_SEPARATOR; static { StringWriter buf = new StringWriter(4); PrintWriter out = new PrintWriter(buf); out.println(); // 获取该系统的换行符 LINE_SEPARATOR =buf.toString(); out.close(); }
private void encryptResource(Resource resource){ InputStream in = null; StringBuilder builder = new StringBuilder(); try { in = resource.getInputStream(); BufferedReader reader =new BufferedReader(new InputStreamReader(in,fileEncoding)); if(CHECK_STRING.equals(reader.readLine())) { return; } String line = null; while ((line =reader.readLine()) != null) { if(StringUtils.isNotBlank(line) && !line.startsWith("#")) { builder.append(line).append(LINE_SEPARATOR); } } } catch (IOExceptione) { e.printStackTrace(); }finally { if(in !=null) { try { in.close(); } catch (IOExceptione) { e.printStackTrace(); } } } try { String source = builder.toString(); if(source.length() > 0) { Path path = Paths.get(resource.getURI()); Files.write(path, (CHECK_STRING +LINE_SEPARATOR + AESUtil.AESEncode(ENCRYPT_STRING,source)).getBytes(fileEncoding)); } } catch (IOExceptione) { e.printStackTrace(); } }
private Resource decryptionResource(Resourceresource){ InputStream in = null; try { in = resource.getInputStream(); BufferedReader reader =new BufferedReader(new InputStreamReader(in)); StringBuilder builder =new StringBuilder(); String firstLine =reader.readLine(); if(!CHECK_STRING.equals(firstLine)) { returnresource; } String line = null; while ((line =reader.readLine())!= null) { builder.append(line); } String decodeString =AESUtil.AESDncode(ENCRYPT_STRING,builder.toString().trim()); return new InputStreamResource(new ByteArrayInputStream(decodeString.getBytes(fileEncoding)),this.fileEncoding); } catch (IOExceptione) { e.printStackTrace(); } finally { if(in !=null) { try { in.close(); } catch (IOExceptione) { e.printStackTrace(); } } } returnresource; }
@Override public void setLocations(Resource... locations) { super.setLocations(locations); this.locations =locations; for (Resourceresource : locations) { encryptResource(resource); } }
/* (non-Javadoc) * @see org.springframework.core.io.support.PropertiesLoaderSupport#loadProperties(java.util.Properties) */ @Override protected void loadProperties(Properties props)throws IOException { if (this.locations !=null) { for (Resourcelocation : this.locations) { if (logger.isInfoEnabled()) { logger.info("Loading properties file from " +location); } try { InputStream stream =null; Reader reader =null; EncodedResource resource =new EncodedResource(decryptionResource(location),this.fileEncoding); try { String filename =resource.getResource().getFilename(); if (filename !=null && filename.endsWith(".xml")) { stream =resource.getInputStream(); propertiesPersister.loadFromXml(props,stream); } elseif (resource.requiresReader()) { reader =resource.getReader(); propertiesPersister.load(props,reader); } else { stream =resource.getInputStream(); propertiesPersister.load(props,stream); } } finally { if (stream !=null) { stream.close(); } if (reader !=null) { reader.close(); } } } catch (IOExceptionex) { ex.printStackTrace(); } } } }
/* (non-Javadoc) * @see org.springframework.core.io.support.PropertiesLoaderSupport#setPropertiesPersister(org.springframework.util.PropertiesPersister) */ @Override public void setPropertiesPersister(PropertiesPersister propertiesPersister) { super.setPropertiesPersister(propertiesPersister); this.propertiesPersister = (propertiesPersister !=null ? propertiesPersister : new DefaultPropertiesPersister()); }
@Override public void setFileEncoding(String encoding) { super.setFileEncoding(encoding); this.fileEncoding =encoding; } } |
配置文件修改
<bean id="propertyConfigurer" class="utils.EncryptPropertyPlaceHolderConfigurer"> <property name="fileEncoding" value="ISO-8859-1" /> <property name="locations"> <list> <value>classpath:db.properties</value> </list> </property> <property name="ignoreUnresolvablePlaceholders" value="true" /> <property name="ignoreResourceNotFound" value="true"/> </bean> |