2 * ============LICENSE_START=======================================================
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 * ============LICENSE_END=========================================================
25 package org.onap.appc.design.services.util;
27 import java.security.Provider;
28 import java.security.Provider.Service;
29 import java.security.Security;
31 import org.jasypt.contrib.org.apache.commons.codec_1_3.binary.Base64;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
36 * This class is used to encapsulate the encryption and decryption support in one place and to
37 * provide a utility to encrypt and decrypt data.
39 public class EncryptionTool {
42 * The prefix we insert onto any data we encrypt so that we can tell if it is encrpyted later and
43 * therefore decrypt it
45 public static final String ENCRYPTED_VALUE_PREFIX = "enc:";
48 * The instance of the encryption utility object
50 private static EncryptionTool instance = null;
53 * The logger for this class.
55 private static final Logger LOG = LoggerFactory.getLogger(EncryptionTool.class);
58 * The secret passphrase (PBE) that we use to perform encryption and decryption. The algorithm we
59 * are using is a symmetrical cipher.
61 private static char[] secret = {'C', '_', 'z', 'l', '!', 'K', '!', '4', '?', 'O', 'z', 'E', 'K', 'E', '>', 'U', 'R',
62 '/', '%', 'Y', '\\', 'f', 'b', '"', 'e', 'n', '{', '"', 'l', 'U', 'F', '+', 'E', '\'', 'R', 'T', 'p', '1',
63 'V', '4', 'l', 'a', '9', 'w', 'v', '5', 'Z', '#', 'i', 'V', '"', 'd', 'l', '!', 'L', 'M', 'g', 'L', 'Q',
64 '{', 'v', 'v', 'K', 'V'};
69 * Get an instance of the EncryptionTool
71 * @return The encryption tool to be used
73 public static final synchronized EncryptionTool getInstance() {
74 if (instance == null) {
75 instance = new EncryptionTool();
81 * Create the EncryptionTool instance
83 private EncryptionTool() {
85 StringBuilder sb = new StringBuilder("Found the following security algorithms:");
86 for (Provider p : Security.getProviders()) {
87 for (Service s : p.getServices()) {
88 String algo = s.getAlgorithm();
89 sb.append(String.format("%n -Algorithm [ %s ] in provider [ %s ] and service [ %s ]", algo, p.getName(),
93 if (LOG.isDebugEnabled()) {
94 LOG.debug(sb.toString());
99 * Decrypt the provided encrypted text
101 * @param cipherText THe cipher text to be decrypted. If the ciphertext is not encrypted, then it is
103 * @return the clear test of the (possibly) encrypted value. The original value if the string is not
106 public synchronized String decrypt(String cipherText) {
107 if (isEncrypted(cipherText)) {
108 String encValue = cipherText.substring(ENCRYPTED_VALUE_PREFIX.length());
109 byte[] plainByte = Base64.decodeBase64(encValue.getBytes());
110 byte[] decryptByte = xorWithSecret(plainByte);
111 return new String(decryptByte);
119 * Encrypt the provided clear text
121 * @param clearText The clear text to be encrypted
122 * @return the encrypted text. If the clear text is empty (null or zero length), then an empty
123 * string is returned. If the clear text is already encrypted, it is not encrypted again and
124 * is returned as is. Otherwise, the clear text is encrypted and returned.
126 public synchronized String encrypt(String clearText) {
127 if (clearText != null) {
128 byte[] encByte = xorWithSecret(clearText.getBytes());
129 String encryptedValue = new String(Base64.encodeBase64(encByte));
130 return ENCRYPTED_VALUE_PREFIX + encryptedValue;
137 * Is a value encrypted? A value is considered to be encrypted if it begins with the
138 * {@linkplain #ENCRYPTED_VALUE_PREFIX encrypted value prefix}.
140 * @param value the value to check.
141 * @return true/false;
143 private static boolean isEncrypted(final String value) {
144 return value != null && value.startsWith(ENCRYPTED_VALUE_PREFIX);
148 * XORs the input byte array with the secret key, padding 0x0 to the end of the secret key if the
149 * input is longer and returns a byte array the same size as input
151 * @param inp The byte array to be XORed with secret
152 * @return A byte array the same size as inp or null if input is null.
154 private byte[] xorWithSecret(byte[] inp) {
159 byte[] secretBytes = new String(secret).getBytes();
160 int size = inp.length;
162 byte[] out = new byte[size];
163 for (int i = 0; i < size; i++) {
164 out[i] = (byte) ((inp[i]) ^ (secretBytes[i % secretBytes.length]));