Second part of onap rename
[appc.git] / appc-config / appc-config-adaptor / provider / src / main / java / org / onap / appc / ccadaptor / EncryptionTool.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APP-C
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.onap.appc.ccadaptor;
22
23 import java.security.Provider;
24 import java.security.Provider.Service;
25 import java.security.Security;
26
27 import javax.crypto.Cipher;
28
29 import org.jasypt.contrib.org.apache.commons.codec_1_3.binary.Base64;
30 import org.jasypt.util.text.BasicTextEncryptor;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 /**
35  * This class is used to encapsulate the encryption and decryption support in one place and to provide a utility to
36  * encrypt and decrypt data.
37  */
38 public class EncryptionTool {
39
40     /**
41      * This lock object is used ONLY if the singleton has not been set up.
42      */
43     private static final Object lock = new Object();
44
45     /**
46      * The salt is used to initialize the PBE (password Based Encrpytion) algorithm.
47      */
48     private static final byte[] DEFAULT_SALT = {
49         (byte) 0xc7, (byte) 0x73, (byte) 0x21, (byte) 0x8c, (byte) 0x7e, (byte) 0xc8, (byte) 0xee, (byte) 0x99
50     };
51
52     /**
53      * The prefix we insert onto any data we encrypt so that we can tell if it is encrpyted later and therefore decrypt
54      * it
55      */
56     @SuppressWarnings("nls")
57     public static final String ENCRYPTED_VALUE_PREFIX = "enc:";
58
59     /**
60      * The instance of the encryption utility object
61      */
62     private static EncryptionTool instance = null;
63
64     /**
65      * The iteration count used to initialize the PBE algorithm and to generate the key spec
66      */
67     private static final int ITERATION_COUNT = 20;
68
69     /**
70      * The logger for this class.
71      */
72     private static final Logger LOG = LoggerFactory.getLogger(EncryptionTool.class);
73
74     /**
75      * The secret passphrase (PBE) that we use to perform encryption and decryption. The algorithm we are using is a
76      * symmetrical cipher.
77      */
78     private static char[] secret = {
79         'C', '_', 'z', 'l', '!', 'K', '!', '4', '?', 'O', 'z', 'E', 'K', 'E', '>', 'U', 'R', '/', '%', 'Y', '\\', 'f',
80         'b', '"', 'e', 'n', '{', '"', 'l', 'U', 'F', '+', 'E', '\'', 'R', 'T', 'p', '1', 'V', '4', 'l', 'a', '9', 'w',
81         'v', '5', 'Z', '#', 'i', 'V', '"', 'd', 'l', '!', 'L', 'M', 'g', 'L', 'Q', '{', 'v', 'v', 'K', 'V'
82     };
83
84     /**
85      * The algorithm to encrypt and decrpyt data is "Password (or passphrase) Based Encryption with Message Digest #5
86      * and the Data Encryption Standard", i.e., PBEWithMD5AndDES.
87      */
88     @SuppressWarnings("nls")
89     private static final String SECURITY_ALGORITHM = "PBEWITHMD5AND256BITAES";// "PBEWithMD5AndDES";
90
91     /**
92      * The decryption cipher object
93      */
94     private Cipher decryptCipher = null;
95
96     /**
97      * The encryption cipher object
98      */
99     private Cipher encryptCipher = null;
100
101     private BasicTextEncryptor encryptor;
102
103     /**
104      * Get an instance of the EncryptionTool
105      *
106      * @return The encryption tool to be used
107      */
108     public static final EncryptionTool getInstance() {
109         if (instance == null) {
110             synchronized (lock) {
111                 if (instance == null) {
112                     instance = new EncryptionTool();
113                 }
114             }
115         }
116         return instance;
117     }
118
119     /**
120      * Create the EncryptionTool instance
121      */
122     @SuppressWarnings("nls")
123     private EncryptionTool() {
124         // encryptor = new BasicTextEncryptor();
125         // encryptor.setPassword(secret.toString());
126         String out = "Found the following security algorithms:";
127         for (Provider p : Security.getProviders()) {
128             for (Service s : p.getServices()) {
129                 String algo = s.getAlgorithm();
130                 out +=
131                     String.format("\n  -Algorithm [ %s ] in provider [ %s ] and service [ %s ]", algo, p.getName(),
132                         s.getClassName());
133             }
134         }
135         LOG.debug(out);
136     }
137
138     /**
139      * Decrypt the provided encrypted text
140      *
141      * @param cipherText
142      *            THe cipher text to be decrypted. If the ciphertext is not encrypted, then it is returned as is.
143      * @return the clear test of the (possibly) encrypted value. The original value if the string is not encrypted.
144      */
145     @SuppressWarnings("nls")
146     public synchronized String decrypt(String cipherText) {
147         if (isEncrypted(cipherText)) {
148             String encValue = cipherText.substring(ENCRYPTED_VALUE_PREFIX.length());
149             // return encryptor.decrypt(encValue);
150             byte[] plainByte = Base64.decodeBase64(encValue.getBytes());
151             byte[] decryptByte = xorWithSecret(plainByte);
152             return new String(decryptByte);
153         } else {
154             return cipherText;
155         }
156
157     }
158
159     /**
160      * Encrypt the provided clear text
161      *
162      * @param clearText
163      *            The clear text to be encrypted
164      * @return the encrypted text. If the clear text is empty (null or zero length), then an empty string is returned.
165      *         If the clear text is already encrypted, it is not encrypted again and is returned as is. Otherwise, the
166      *         clear text is encrypted and returned.
167      */
168     @SuppressWarnings("nls")
169     public synchronized String encrypt(String clearText) {
170         if (clearText != null) {
171             byte[] encByte = xorWithSecret(clearText.getBytes());
172             String encryptedValue = new String(Base64.encodeBase64(encByte));
173             return ENCRYPTED_VALUE_PREFIX + encryptedValue;
174         } else {
175             return null;
176         }
177     }
178
179     /**
180      * Is a value encrypted? A value is considered to be encrypted if it begins with the
181      * {@linkplain #ENCRYPTED_VALUE_PREFIX encrypted value prefix}.
182      *
183      * @param value
184      *            the value to check.
185      * @return true/false;
186      */
187     private static boolean isEncrypted(final String value) {
188         return value != null && value.startsWith(ENCRYPTED_VALUE_PREFIX);
189     }
190
191     /**
192      * XORs the input byte array with the secret key, padding 0x0 to the end of the secret key if the input is longer
193      * and returns a byte array the same size as input
194      *
195      * @param inp
196      *            The byte array to be XORed with secret
197      * @return A byte array the same size as inp or null if input is null.
198      */
199     private byte[] xorWithSecret(byte[] inp) {
200         if (inp == null) {
201             return null;
202         }
203
204         byte[] secretBytes = new String(secret).getBytes();
205         int size = inp.length;
206
207         byte[] out = new byte[size];
208         for (int i = 0; i < size; i++) {
209             out[i] = (byte) ((inp[i]) ^ (secretBytes[i % secretBytes.length]));
210         }
211         return out;
212     }
213
214 }