actually adding the files to the initial commit
[vid.git] / vid / src / main / java / org / openecomp / vid / encryption / EncryptedConfiguration.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * VID
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.vid.encryption;
22
23 import java.io.FileInputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.security.MessageDigest;
27 import java.util.Properties;
28
29 import javax.crypto.Cipher;
30 import javax.crypto.spec.SecretKeySpec;
31
32 import org.apache.commons.cli.CommandLine;
33 import org.apache.commons.cli.CommandLineParser;
34 import org.apache.commons.cli.DefaultParser;
35 import org.apache.commons.cli.Options;
36 import org.apache.commons.cli.ParseException;
37 import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
38
39
40 /**
41  *  Class to manage encrypted configuration values.
42  */
43 public class EncryptedConfiguration {
44         
45         /** The logger. */
46         static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(EncryptedConfiguration.class);
47
48
49           /**   Our secret key and method. */
50           private String encryptionKey;
51           
52         /** The encryption method. */
53         private String encryptionMethod;
54
55           /**
56          *      Where to log when things go wrong.
57          *
58          * @param key the key
59          * @param method the method
60          */
61
62           public EncryptedConfiguration(String key, String method) {
63             encryptionKey = key.trim();
64             encryptionMethod = method;
65           } 
66
67           /**
68          * Retrieve an encrypted string from the given configuration.
69          * The name will have ".x" appended to it.
70          * Decoded from hex, it will be "method:hexsalt:hexvalue".
71          * The format of the value will be in hex.
72          * Method will be "r" to begin with, for "rc4".
73          *
74          * @param f the f
75          * @param name the name
76          * @param deflt the deflt
77          * @return the string
78          * @throws Exception the exception
79          */
80           public String getString(String f, String name, String deflt)
81           throws Exception {
82             logger.debug(EELFLoggerDelegate.debugLogger, "==> getString"); 
83             return getString(f, name, deflt, encryptionKey);
84           }
85
86           /**
87          * Retrieve an encrypted string from the given configuration.
88          * The name will have ".x" appended to it.
89          * Decoded from hex, it will be "method:hexsalt:hexvalue".
90          * The format of the value will be in hex.
91          * Method will be "r" to begin with, for "rc4".
92          *
93          * @param f the f
94          * @param name the name
95          * @param deflt the deflt
96          * @param key the key
97          * @return the string
98          * @throws Exception the exception
99          */
100           public String getString(String f, String name, String deflt, String key)
101            throws Exception {
102
103             logger.debug(EELFLoggerDelegate.debugLogger, "==> getString"); 
104             logger.debug(EELFLoggerDelegate.debugLogger, "  key = " + key);
105             Properties prop = new Properties();
106             InputStream input = null;
107
108             try {
109               input = new FileInputStream(f);
110
111               prop.load(input);
112
113               /* for testing, a dump of all key-value pairs
114               Enumeration<?> e = prop.propertyNames();
115               while (e.hasMoreElements()) {
116                 String k = (String) e.nextElement();
117                 String value = prop.getProperty(k);
118                 System.out.println("Key : " + k + ", Value : " + value);
119               }
120               */
121
122             } catch (IOException ex) {
123               ex.printStackTrace(); // TODO: fix
124             } finally {
125               input.close();
126             }
127
128             String str = prop.getProperty(name + ".x");
129             logger.debug(EELFLoggerDelegate.debugLogger, "str = " + str);
130
131             if (str == null) {
132               // not encrypted version
133               str = prop.getProperty(name);
134               if (str == null) {
135                 return deflt;
136               }
137               return str;
138             }
139
140             String method = encryptionMethod;
141             logger.debug(EELFLoggerDelegate.debugLogger, "method = " + method);
142             String salt = EncryptedConfiguration.generateSalt();
143             logger.debug(EELFLoggerDelegate.debugLogger, "salt = " + salt);
144
145             return decrypt(str, key, method, salt);
146           }
147
148           /**
149          * Decrypt a string in 'method:hexsalt:hexvalue' format.
150          *
151          * @param triple the triple
152          * @param key the key
153          * @param method the method
154          * @param salt the salt
155          * @return the string
156          * @throws Exception the exception
157          */
158           public static String decrypt(String triple, String key, String method, String salt) throws Exception {
159             /*
160             String[] strParts = triple.trim().split(":");
161             if (strParts.length != 3) throw new Exception("Encrypted value must look like 'x:y:z'");
162             return decrypt(strParts[0], Convert.stringFromHex(strParts[1]), key, Convert.bytesFromHex(strParts[2]));
163             */
164
165             return decrypt(method, salt, key, EncryptConvertor.bytesFromHex(triple)); 
166           }
167
168           /**
169          * Decrypt a string 'method:hexsalt:hexvalue' format.
170          *
171          * @param method the method
172          * @param salt the salt
173          * @param key the key
174          * @param bvalue the bvalue
175          * @return the string
176          * @throws Exception the exception
177          */
178           public static String decrypt(String method, String salt, String key, byte[] bvalue) throws Exception {
179             logger.debug(EELFLoggerDelegate.debugLogger, "==> decrypt method");
180             logger.debug(EELFLoggerDelegate.debugLogger, "  method = " + method);
181             logger.debug(EELFLoggerDelegate.debugLogger, "  salt = " + salt);
182             logger.debug(EELFLoggerDelegate.debugLogger, "  key = " + key);
183             byte[] secretKey = runDigest(salt + "." + key);
184
185             SecretKeySpec skeySpec = new SecretKeySpec(secretKey, method);
186
187             Cipher cipher = Cipher.getInstance(method); // "AES"
188             cipher.init(Cipher.DECRYPT_MODE, skeySpec);
189
190             byte[] decrypted = cipher.doFinal(bvalue);
191             return new String(decrypted);
192           }
193
194           /**
195          * Encrypt a string using the given method, salt and key.
196          *
197          * @param method the method
198          * @param salt the salt
199          * @param key the key
200          * @param value the value
201          * @return the byte[]
202          * @throws Exception the exception
203          */
204           public static byte[] encrypt(String method, String salt, String key, String value) throws Exception {
205             logger.debug(EELFLoggerDelegate.debugLogger, "==> encrypt() method");
206             byte[] bvalue = value.getBytes();
207             byte[] secretKey = runDigest(salt + "." + key);
208
209             SecretKeySpec skeySpec = new SecretKeySpec(secretKey, method);
210
211             Cipher cipher = Cipher.getInstance(method); // "AES"
212             cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
213
214             byte[] encrypted = cipher.doFinal(bvalue);
215             return encrypted;
216           }
217
218           /**
219          * Prepare a secret key by running a digest on it.
220          *
221          * @param text the text
222          * @return the byte[]
223          * @throws Exception the exception
224          */
225           private static byte[] runDigest(String text) throws Exception {
226             logger.debug(EELFLoggerDelegate.debugLogger, "==> runDigest() method");
227             MessageDigest md = MessageDigest.getInstance("MD5");
228             md.reset();
229             md.update(text.getBytes(), 0, text.length());
230             return md.digest();
231           }
232
233           /**
234          * Encrypt a string using the given method, salt and key, and return it as a hex-formated triple.
235          *
236          * @param method the method
237          * @param salt the salt
238          * @param key the key
239          * @param value the value
240          * @return the string
241          * @throws Exception the exception
242          */
243           public static String encryptToTriple(String method, String salt, String key, String value) throws Exception {
244             logger.debug(EELFLoggerDelegate.debugLogger, "==> Enter encryptToTriple()");
245             logger.debug(EELFLoggerDelegate.debugLogger, "method = " + method);
246             logger.debug(EELFLoggerDelegate.debugLogger, "salt = " + salt);
247             logger.debug(EELFLoggerDelegate.debugLogger, "key = " + key);
248             logger.debug(EELFLoggerDelegate.debugLogger, "valye = " + value);
249            
250             /* 
251             StringBuffer sb = new StringBuffer(method);
252               sb.append(":").append(Convert.toHexString(salt))
253               .append(":").append(Convert.toHexString(encrypt(method, salt, key, value)));
254             logger.debug("s = " + sb.toString());
255             */
256
257             StringBuffer sb2 = new StringBuffer("");
258             sb2.append(EncryptConvertor.toHexString(encrypt(method, salt, key, value)));
259             String s = sb2.toString();
260             logger.debug(EELFLoggerDelegate.debugLogger, "s = " + s);
261             return s;
262           }
263
264           /**
265          * Create a value that can be used as a salt.
266          *
267          * @return the string
268          */
269           public static String generateSalt() {
270             logger.debug(EELFLoggerDelegate.debugLogger, "==> generaltSalt");
271
272             // G2 wants to hard code the value for salt.
273             // set the value as 123456789
274             // return Long.toString(System.currentTimeMillis() % 1000) + Pid.getPidStr();
275             return Long.toString(123456789 % 10000);
276           }
277
278           /**
279          * Usage.
280          */
281         public static void usage() {
282             usage(null);
283           }
284
285           /**
286          * Usage.
287          *
288          * @param msg the msg
289          */
290         public static void usage(String msg) {
291             if (msg != null) System.out.println(msg);
292             System.out.println("Usage: java EncryptedConfiguration -D triple -k key\n" +
293               "java EncryptedConfiguration -d string -m method [-s salt | -S] -k key\n" +
294               "java EncryptedConfiguration -e string -m method [-s salt | -S] -k key\n" +
295               "-D\tdecrypt x:y:z triple\n" +
296                     "-d\tdecrypt string (in hex)\n" +
297                     "-e\tencrypt string\n" +
298                     "-S\tgenerate a salt\n"
299                     );
300              System.exit(1);
301           }
302
303
304
305         /**
306          * The main method.
307          *
308          * @param args the arguments
309          */
310         public static void main(String[] args) {
311
312                 Options options = new Options();
313             options.addOption("s", true, "salt");
314             options.addOption("S", false, "Generate salt");
315             options.addOption("k", true, "key");
316             options.addOption("m", true, "method");
317             options.addOption("e", true, "encryptString");
318             options.addOption("d", true, "decryptString");
319             options.addOption("D", true, "triple x:y:z");
320             options.addOption("h", false, "show help");
321             options.addOption("?", false, "show help");
322
323             String salt = null, key = null, method = null, encStr = null, decStr = null, triple = null;
324             boolean genSalt = false;
325
326             CommandLineParser parser = new DefaultParser();
327             CommandLine cmd = null;
328             
329             try {
330                 cmd = parser.parse(options, args);
331                 
332                 System.out.println("You picked " + cmd.toString() + "\n");
333                 if (cmd.hasOption("s")) {
334                         salt = cmd.getOptionValue("s");
335                 }
336                 if (cmd.hasOption("S")) {
337                         genSalt = true;
338                         System.out.println("here in S");                
339                 }
340                 if (cmd.hasOption("k")) {
341                         key = cmd.getOptionValue("k");
342                 }
343                 if (cmd.hasOption("m")) {
344                         method = cmd.getOptionValue("m");
345                 }
346                 if (cmd.hasOption("e")) {
347                         encStr = cmd.getOptionValue("e");
348                 }
349                 if (cmd.hasOption("d")) {
350                         decStr = cmd.getOptionValue("d");
351                 }
352                 if (cmd.hasOption("D")) {
353                         triple = cmd.getOptionValue("D");
354                 }
355                 if (cmd.hasOption("?") || cmd.hasOption("h")) {
356                         usage();
357                         System.exit(0);
358                 }
359
360             if (triple == null) {
361               if ((salt == null) && !genSalt) usage("one of -s or -S must be specified");
362               if ((salt != null) && genSalt) usage("only one of -s or -S must be specified");
363               if (key == null) usage("-k must be specified");
364               if (method == null) usage("-m must be specified");
365               if ((encStr == null) && (decStr == null)) usage("one of -d or -e must be specified");
366               if ((encStr != null) && (decStr != null)) usage("only one of -d or -e may be specified");
367               if (genSalt) {
368                 salt = generateSalt();
369                 System.out.println("salt = " + salt);
370               }
371
372               if (encStr != null)
373                 System.out.println(encryptToTriple(method, salt, key, encStr));
374               if (decStr != null)
375                 System.out.println(decrypt(method, salt, key, EncryptConvertor.bytesFromHex(decStr)));
376             } else {
377               if (key == null) {
378                   usage("-k not specified");
379                   System.exit(0);
380               }
381                   System.out.println(decrypt(triple, key, method, salt));
382             }
383             
384             } catch (ParseException e) {
385                     System.out.println("Failed to parse command line properties e="+e.toString());
386             } catch (Exception e) {
387                     System.out.println("Failed to run EncryptedConfiguration main() e="+e.toString());
388             }
389
390                 // http://forums.sun.com/thread.jspa?threadID=5290983
391                 // try {
392                 //     String message = "Strong Versus Unlimited Strength Cryptography";
393                 //     SecretKeySpec skeySpec = new SecretKeySpec("0123456789ABCDEF".getBytes(), "AES"); //AES-128
394
395                 //     Cipher cipher = Cipher.getInstance("AES");       // "AES/ECB/NoPadding"
396                 //     cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
397
398                 //     byte[] encrypted = cipher.doFinal(message.getBytes());
399                 //     System.out.println("encrypted string: " + encrypted); //storing into MySQL DB
400                 //     System.out.println("in hex: '" + Convert.toHexString(encrypted) + "'");
401
402                 //     cipher.init(Cipher.DECRYPT_MODE, skeySpec);
403                 //     byte[] original = cipher.doFinal(encrypted);
404                 //     String originalString = new String(original);
405                 //     System.out.println("Original string: " + originalString);
406                 // } catch (Exception e) {
407                 //     System.err.println("Exception caught: " + e.toString());
408                 // }
409         System.exit(0);
410
411         }
412
413 }