View Javadoc

1   /*
2    * Copyright 2012-2013 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.properties.api.core.security;
17  
18  import static de.smartics.properties.api.core.security.SecurityConfigurationLoader.SECURITY_ID;
19  import static de.smartics.properties.api.core.security.SecurityConfigurationLoader.SECURITY_ALGORITHM;
20  import static de.smartics.properties.api.core.security.SecurityConfigurationLoader.SECURITY_KEY;
21  import static de.smartics.properties.api.core.security.SecurityConfigurationLoader.SECURITY_PROVIDER;
22  import static de.smartics.properties.api.core.security.SecurityConfigurationLoader.SECURITY_TRANSFORMATION;
23  
24  import java.util.Properties;
25  
26  import javax.crypto.Cipher;
27  import javax.crypto.SecretKey;
28  import javax.crypto.spec.SecretKeySpec;
29  
30  import org.apache.commons.codec.binary.Base64;
31  import org.apache.commons.lang.StringUtils;
32  
33  import de.smartics.properties.api.core.domain.PropertyDescriptor;
34  
35  /**
36   * Base implementation based on Java security, loading configuration values from
37   * a properties file stored in
38   * {@link SecurityConfigurationLoader#CLASSPATH_LOCATION}.
39   */
40  public class PropertiesBasedPropertyValueSecurity extends
41      AbstractPropertyValueSecurity
42  
43  {
44    // ********************************* Fields *********************************
45  
46    // --- constants ------------------------------------------------------------
47  
48    /**
49     * The class version identifier.
50     */
51    private static final long serialVersionUID = 1L;
52  
53    // --- members --------------------------------------------------------------
54  
55    /**
56     * The security properties to create key and cipher.
57     *
58     * @serial
59     */
60    private final Properties properties;
61  
62    /**
63     * The symmetric key to en- and decrypt property values.
64     *
65     * @serial
66     */
67    private final SecretKey key;
68  
69    // ****************************** Initializer *******************************
70  
71    // ****************************** Constructors ******************************
72  
73    /**
74     * Default constructor.
75     */
76    public PropertiesBasedPropertyValueSecurity()
77    {
78      properties = loadProperties();
79      key = createKey(properties);
80    }
81  
82    // ****************************** Inner Classes *****************************
83  
84    // ********************************* Methods ********************************
85  
86    // --- init -----------------------------------------------------------------
87  
88    private Properties loadProperties()
89    {
90      try
91      {
92        final SecurityConfigurationLoader loader =
93            new SecurityConfigurationLoader();
94        return loader.load();
95      }
96      catch (final IllegalStateException e)
97      {
98        throw new SecurityException(new SecurityMessageBean(
99            SecurityCode.LOADING_SECURITY_PROPERTIES_FAILED, e,
100           properties.getProperty(SECURITY_ID)));
101     }
102   }
103 
104   /**
105    * Creates the symmetric key instance.
106    *
107    * @param descriptor the descriptor of the property whose value is to be
108    *          secured.
109    * @return the symmetric key instance ready to be used.
110    * @throws SecurityException on any problem creating the symmetric key
111    *           instance.
112    */
113   private SecretKey createKey(final Properties properties)
114     throws SecurityException
115   {
116     final String key = properties.getProperty(SECURITY_KEY);
117     final String encryptAlgorithm = properties.getProperty(SECURITY_ALGORITHM);
118 
119     try
120     {
121       final byte[] decodedKey = Base64.decodeBase64(key);
122 
123       final SecretKeySpec secretKey =
124           new SecretKeySpec(decodedKey, encryptAlgorithm);
125       return secretKey;
126     }
127     catch (final Exception e)
128     {
129       throw new SecurityException(new SecurityMessageBean(
130           SecurityCode.INIT_KEY_GENERATION_FAILED, e,
131           properties.getProperty(SECURITY_ID)));
132     }
133   }
134 
135   // --- get&set --------------------------------------------------------------
136 
137   // --- business -------------------------------------------------------------
138 
139   @Override
140   public String decrypt(final PropertyDescriptor descriptor,
141       final String encryptedValue) throws NullPointerException,
142     SecurityException
143   {
144     final Cipher cipher = createCipher();
145     return decrypt(descriptor, encryptedValue, key, cipher);
146   }
147 
148   @Override
149   public String encrypt(final PropertyDescriptor descriptor,
150       final String plainValue) throws NullPointerException, SecurityException
151   {
152     final Cipher cipher = createCipher();
153     return encrypt(descriptor, plainValue, key, cipher);
154   }
155 
156   private Cipher createCipher() throws SecurityException
157   {
158     final String transformation =
159         properties.getProperty(SECURITY_TRANSFORMATION);
160     final String provider = properties.getProperty(SECURITY_PROVIDER);
161 
162     try
163     {
164       if (StringUtils.isNotEmpty(provider))
165       {
166         return Cipher.getInstance(transformation, provider);
167       }
168       else
169       {
170         return Cipher.getInstance(transformation);
171       }
172     }
173     catch (final Exception e)
174     {
175       throw new SecurityException(new SecurityMessageBean(
176           SecurityCode.INIT_CIPHER_GENERATION_FAILED, e,
177           properties.getProperty(SECURITY_ID)));
178     }
179   }
180 
181   // --- object basics --------------------------------------------------------
182 
183 }