d05a99be8833ee54a03b5cc64f6b2219701586c0
[appc.git] / appc-config / appc-encryption-tool / provider / src / main / java / org / openecomp / appc / encryptiontool / wrapper / EncryptionTool.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Copyright (C) 2017 Amdocs
8  * =============================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * 
21  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  * ============LICENSE_END=========================================================
23  */
24 package org.onap.appc.encryptiontool.wrapper;
25
26 import java.security.Provider;
27 import java.security.Provider.Service;
28 import java.security.Security;
29
30 import org.jasypt.contrib.org.apache.commons.codec_1_3.binary.Base64;
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
36  * provide a utility to encrypt and decrypt data.
37  */
38 public class EncryptionTool {
39
40     /**
41      * The prefix we insert onto any data we encrypt so that we can tell if it is encrpyted later and
42      * therefore decrypt it
43      */
44     public static final String ENCRYPTED_VALUE_PREFIX = "enc:";
45
46     /**
47      * The instance of the encryption utility object
48      */
49     private static EncryptionTool instance = null;
50
51     /**
52      * The logger for this class.
53      */
54     private static final Logger LOG = LoggerFactory.getLogger(EncryptionTool.class);
55
56     /**
57      * The secret passphrase (PBE) that we use to perform encryption and decryption. The algorithm we
58      * are using is a symmetrical cipher.
59      */
60     private static char[] secret = {'C', '_', 'z', 'l', '!', 'K', '!', '4', '?', 'O', 'z', 'E', 'K', 'E', '>', 'U', 'R',
61             '/', '%', 'Y', '\\', 'f', 'b', '"', 'e', 'n', '{', '"', 'l', 'U', 'F', '+', 'E', '\'', 'R', 'T', 'p', '1',
62             'V', '4', 'l', 'a', '9', 'w', 'v', '5', 'Z', '#', 'i', 'V', '"', 'd', 'l', '!', 'L', 'M', 'g', 'L', 'Q',
63             '{', 'v', 'v', 'K', 'V'};
64
65
66
67     /**
68      * Get an instance of the EncryptionTool
69      *
70      * @return The encryption tool to be used
71      */
72     public static final synchronized EncryptionTool getInstance() {
73         if (instance == null) {
74             instance = new EncryptionTool();
75         }
76         return instance;
77     }
78
79     /**
80      * Create the EncryptionTool instance
81      */
82     private EncryptionTool() {
83
84         StringBuilder sb = new StringBuilder("Found the following security algorithms:");
85         for (Provider p : Security.getProviders()) {
86             for (Service s : p.getServices()) {
87                 String algo = s.getAlgorithm();
88                 sb.append(String.format("%n -Algorithm [ %s ] in provider [ %s ] and service [ %s ]", algo, p.getName(),
89                         s.getClassName()));
90             }
91         }
92         if (LOG.isDebugEnabled()) {
93             LOG.debug(sb.toString());
94         }
95     }
96
97     /**
98      * Decrypt the provided encrypted text
99      *
100      * @param cipherText THe cipher text to be decrypted. If the ciphertext is not encrypted, then it is
101      *        returned as is.
102      * @return the clear test of the (possibly) encrypted value. The original value if the string is not
103      *         encrypted.
104      */
105     public synchronized String decrypt(String cipherText) {
106         if (isEncrypted(cipherText)) {
107             String encValue = cipherText.substring(ENCRYPTED_VALUE_PREFIX.length());
108             byte[] plainByte = Base64.decodeBase64(encValue.getBytes());
109             byte[] decryptByte = xorWithSecret(plainByte);
110             return new String(decryptByte);
111         } else {
112             return cipherText;
113         }
114
115     }
116
117     /**
118      * Encrypt the provided clear text
119      *
120      * @param clearText The clear text to be encrypted
121      * @return the encrypted text. If the clear text is empty (null or zero length), then an empty
122      *         string is returned. If the clear text is already encrypted, it is not encrypted again and
123      *         is returned as is. Otherwise, the clear text is encrypted and returned.
124      */
125     public synchronized String encrypt(String clearText) {
126         if (clearText != null) {
127             byte[] encByte = xorWithSecret(clearText.getBytes());
128             String encryptedValue = new String(Base64.encodeBase64(encByte));
129             return ENCRYPTED_VALUE_PREFIX + encryptedValue;
130         } else {
131             return null;
132         }
133     }
134
135     /**
136      * Is a value encrypted? A value is considered to be encrypted if it begins with the
137      * {@linkplain #ENCRYPTED_VALUE_PREFIX encrypted value prefix}.
138      *
139      * @param value the value to check.
140      * @return true/false;
141      */
142     private static boolean isEncrypted(final String value) {
143         return value != null && value.startsWith(ENCRYPTED_VALUE_PREFIX);
144     }
145
146     /**
147      * XORs the input byte array with the secret key, padding 0x0 to the end of the secret key if the
148      * input is longer and returns a byte array the same size as input
149      *
150      * @param inp The byte array to be XORed with secret
151      * @return A byte array the same size as inp or null if input is null.
152      */
153     private byte[] xorWithSecret(byte[] inp) {
154         if (inp == null) {
155             return new byte[0];
156         }
157
158         byte[] secretBytes = new String(secret).getBytes();
159         int size = inp.length;
160
161         byte[] out = new byte[size];
162         for (int i = 0; i < size; i++) {
163             out[i] = (byte) ((inp[i]) ^ (secretBytes[i % secretBytes.length]));
164         }
165         return out;
166     }
167
168 }