Spring to encrypt and decrypt an attribute specified by the external subordination file

Source: Internet
Author: User
Tags decrypt key string postgresql
In our development, we often use the spring framework to read property values for property files, and then use placeholders to reference property values of property files to simplify configuration and make configurations more flexible and versatile.

such as the following property profile: Db.properties

#数据库配置
Db.driver=org.postgresql.driver
Db.url=jdbc\:p Ostgresql\://10.166.176.127\:5432/test
Db.username=ivsadmin
db.password=123456
Db.name=ivs


Applicationcontext.xml file

<context:property-placeholder location= "classpath:db.properties"/> <bean id= "DataSource
 
   "
class= "Com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method= "Close" >
<property name= "Driverclass" Value= "${db.driver}"/> <property name= "Jdbcurl" value= "
${db.url}"/> <property name=
"User" Value= "${db.username}"/> <property name= "password" value=
"${db.password}"/> <property name=
" Checkouttimeout "value=" 3000 "/>
   </bean>

For some sensitive property values, such as password properties. For security purposes, we typically encrypt passwords.
You might want the user to see db.properties like this:
#数据库配置
Db.driver=org.postgresql.driver
Db.url=jdbc\:p Ostgresql\://10.166.176.127\:5432/ivs
Db.username=ivsadmin
db.password={smc}synzvkgihoprkdghcyt81w==
Db.name=ivs

Here you can see that the value of the password attribute is encrypted, and the other property values are unchanged, thus achieving security purposes. Here is the use of Java 3DES encryption, in the previous article 3DES encryption, decryption tool class has been introduced

Below we start to analyze our requirements:
The configuration of external application parameters in spring is propertyplaceholderconfigurer and Propertyoverrideconfigurer objects, Propertyplaceholderconfigurer implements the Beanfactorypostprocessor interface, it can manage the attribute value in the <bean/> externally.
Just like this:

<bean id= "PropertyConfigurer1" class= "Org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
<property name= "Locations" >
    <value>WEB-INF/classes/db.properties</value>
</property>
  </bean>

To simplify the use of Propertyplaceholderconfigurer, Spring provides <context:property-placeholder/> elements, Like the Applicationcontext.xml file: <context:property-placeholder location= "Classpath:db.properties"/>
It is clear here that we simply inherit the Propertyplaceholderconfigurer object and rewrite the Loadproperties method of the Propertiesloadersupport interface, You can perform related operations on the property values of the subordinate files.

Understand the need to get down to start our implementation code:

Decryptpropertyplaceholderconfigurer.java

Import Java.io.File;
Import Java.io.FileOutputStream;
Import java.io.IOException;
Import Java.io.InputStream;
Import Java.io.InputStreamReader;
 
Import java.util.Properties;
Import Org.apache.commons.lang.StringUtils;
Import Org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
 
Import Org.springframework.core.io.Resource;
 
Import com.huawei.smc.commons.constants.CommonContants; /** * < A statement function brief > * * @author hKF44803 * @version [version number, 2011-12-6] * @see [Related class/method] * @since [Product/Module version]/p 
     
    Ublic class Decryptpropertyplaceholderconfigurer extends Propertyplaceholderconfigurer {private resource[] locations;
     
    Private Decryptpropertiespersister Propertiespersister = new Decryptpropertiespersister ();
     
    Private String fileencoding = "Utf-8";
     
    Private Boolean ignoreresourcenotfound = false; /** * {@inheritDoc} */@Override public void Setlocations (resource[] locations) {This.locat ions = Locations;
        }/** * {@inheritDoc} */@Override public void setfileencoding (String encoding) {
    this.fileencoding = encoding; }/** * {@inheritDoc} */@Override public void Setignoreresourcenotfound (Boolean IGNORERESOURC
    Enotfound) {this.ignoreresourcenotfound = Ignoreresourcenotfound;  }/** * {@inheritDoc} */@Override public void loadproperties (Properties props) throws
            IOException {//property file is an empty if (this.locations!= null) {//Loop Read Property file for (int i = 0; i < this.locations.length i++) {Resource location = This.locatio
                 
                Ns[i];
                InputStream is = null;
                FileOutputStream fos = null;
                     
                    try {is = Location.getinputstream ();Check if the file is an XML file if (Location.getfilename (). EndsWith (xml_file_extension)) {
                    THIS.PROPERTIESPERSISTER.LOADFROMXML (props, is); }//Property file else {This.propertiespersist
                        Er.doload (Props, New InputStreamReader (IS, this.fileencoding));
                         
                        String content = This.propertiesPersister.getEncryptContent ();
                        Find if there is a cryptographic ID if (stringutils.contains (content, Commoncontants.decrypt_flag)) {try {File file = location.g
                                 
                                Etfile ();
                                 
                                FOS = new FileOutputStream (file); Fos.write (This.propertiesPersister.getEncryptContENT (). GetBytes ());
                                 
                            Fos.flush ();
                                finally {if (null!= FOS)
                                {Fos.close (); catch (I
                        Oexception ex) {if (This.ignoreresourcenotfound) { if (logger.iswarnenabled ()) {Logger.warn ("could not load PR
                        Operties from "+ Location +": "+ ex.getmessage ());
                    } else {throw ex;
           }} finally {          
                    if (is!= null) {is.close (); }
                     
                }
            }
        }
    }
}

Where the Propertiespersister variable is implemented with the Defaultpropertiespersister class we write, Decryptpropertiespersister.java object

Import Java.io.BufferedReader;
Import java.io.IOException;
Import Java.io.Reader;
 
Import java.util.Properties;
Import Org.springframework.util.DefaultPropertiesPersister;
 
Import Org.springframework.util.StringUtils;
Import com.huawei.smc.commons.constants.CommonContants;
Import com.huawei.smc.commons.constants.NumberConstants;
 
Import Com.huawei.smc.commons.util.ThreeDesUtil; /** * Heavy Duty Defaultpropertiespersister class * * @author hKF44803 * @version [version number, 2011-12-6] * @see [related classes/methods] * @since [ Product/Module Version] */public class Decryptpropertiespersister extends Defaultpropertiespersister {//encrypted string private Strin
     
    G Encryptcontent;
    Public String getencryptcontent () {return encryptcontent;
        }/** * {@inheritDoc} * * @Override protected void doload (Properties props, reader reader)
         
        Throws IOException {BufferedReader in = new BufferedReader (reader); The last written content StringBuilder sbcontent = New StringBuilder ();
             
            Loop read file while (true) {//read each line String = In.readline ();
            Non-null check if (line = = null) {break;
             
            //Remove Space line = Stringutils.trimleadingwhitespace (line); Read behavior empty, jump out of Loop if (line.length () = = 0) {//length 0, line wrap Sbcontent.appe
                 
                nd ("\ n");
            Continue
             
            }//The first character char Firstchar = Line.charat (0) per line;
            The first character is not # and!
            if (Firstchar!= ' # ' && firstchar!= '! ') {while (endswithcontinuationmarker) {String nextline = In.read
                    Line ();
                     
                   line = line.substring (0, Line.length ()-1); Non-null check if (nextline!= null) {line + = Stringutils.triml
                    Eadingwhitespace (nextline); }//Find index int separatorindex = line.indexof ("=") for all positions of equal sign
                 
                ); No equal sign if (Separatorindex = 1) {Separatorindex = Line.indexof (":")
                ; //Fetch key String key = (Separatorindex!=-1)?
                 
                Line.substring (0, Separatorindex): line; The value of the key is String value = (separatorindex!=-1)?
                 
                Line.substring (Separatorindex + 1): "";
                Remove the Space key = Stringutils.trimtrailingwhitespace (key);
                 
                Value = Stringutils.trimleadingwhitespace (value); Put all of the properties into a persistent property set * Props.put (Unescape (Key), unescape (value)); DB Property File if (CommonContants.DB_PASSWORD_PROPS.equals (key)) {//Instance encryption worker
                     
                    With class Threedesutil desutil = new Threedesutil ();
                        DB Password decryption if (Value.startswith (Commoncontants.decrypt_flag)) {
                         
                        Remove the identity value = value.substring (numberconstants.int_5);
                         
                        3DES decryption of the encrypted property value = Desutil.decrypt (value);
                    The decrypted value is placed in the props Props.put (unescape (key), unescape (value));
                        }//DB password encryption else {//encrypt specified value
                         
                        String Strencrypt = desutil.encrypt (value); // The encrypted value adds an identifier, distinguishing decryption, encrypting value = Commoncontants.decrypt_flag + strencrypt;
                         
                        The Encrypted line = key + commoncontants.properties_seperate + value;
                    Sbcontent.append (line + "\ n"); }//Append additional properties else {Sbcontent.append
                (line + "\ n"); 
            } else {//append-read annotation content sbcontent.append (line + \ n);
    } encryptcontent = Sbcontent.tostring (); }
}

Finally, the following applicationcontext.xml file needs to be modified, as follows:

<bean id= "PropertyConfigurer1" class= "Com.huawei.smc.commons.DecryptPropertyPlaceholderConfigurer" >
<property name= "Locations" >
    <value>WEB-INF/classes/db.properties</value>
</ property>
    </bean>
 
    <bean id= "DataSource" class= "Com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method= "Close" >
<property name= "Driverclass" value= "${db.driver}"/> <property name=
" Jdbcurl "value=" ${db.url} "/>
<property name=" user "value=" ${db.username} "/> <property name=
" Password "value=" ${db.password} "/>
<property name=" checkouttimeout "value=" 3000 "/>
   </bean >

This completes the encryption of the property, and the property is encrypted when spring is finished loading

Tip: If there are multiple profiles in the configuration that need to be loaded, and the property files do not require any processing, add the following configuration:

<bean id= "Propertyconfigurer"
class= " Org.springframework.beans.factory.config.PropertyPlaceholderConfigurer ">
<property name=" Order "value= "1"/>  
        <property name= "Ignoreunresolvableplaceholders" value= "true"/> <property "name=
" Locations ">
<value>WEB-INF/classes/smc.properties</value>
</property>


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.