71ac6151f7fed3b0b89516b2d2f32ceabd1a8764
[sdc.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2019 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.sdc.securityutil;
22
23 import java.security.SecureRandom;
24 import java.util.Arrays;
25 import javax.crypto.Cipher;
26 import javax.crypto.spec.GCMParameterSpec;
27 import javax.crypto.spec.SecretKeySpec;
28 import org.apache.commons.codec.binary.Base64;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 public class CipherUtil {
33
34     private static Logger log = LoggerFactory.getLogger(CipherUtil.class.getName());
35     private static final String ALGORITHM = "AES";
36     private static final String ALGORITHM_DETAILS = ALGORITHM + "/GCM/NoPadding";
37     private static final String CIPHER_PROVIDER = "SunJCE";
38
39     public static final int GCM_TAG_LENGTH = 16;
40     public static final int GCM_IV_LENGTH = 12;
41
42     private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
43     private static final String ALGORITHM_NAME = "SHA1PRNG";
44
45     private CipherUtil() {}
46
47     /**
48      * Encrypt the text using the secret key in key.properties file
49      *
50      * @param value string to encrypt
51      * @return The encrypted string
52      * @throws CipherUtilException In case of issue with the encryption
53      */
54     public static String encryptPKC(String value, String base64key) throws CipherUtilException {
55         Cipher cipher;
56         byte[] iv = new byte[GCM_IV_LENGTH];
57         byte[] finalByte;
58         try {
59             cipher = Cipher.getInstance(ALGORITHM_DETAILS, CIPHER_PROVIDER);
60             SecureRandom secureRandom = SecureRandom.getInstance(ALGORITHM_NAME);
61             secureRandom.nextBytes(iv);
62             GCMParameterSpec spec =
63                 new GCMParameterSpec(GCM_TAG_LENGTH * java.lang.Byte.SIZE, iv);
64             cipher.init(Cipher.ENCRYPT_MODE, getSecretKeySpec(base64key), spec);
65             finalByte = cipher.doFinal(value.getBytes());
66
67         } catch (Exception ex) {
68             log.error("encrypt failed", ex);
69             throw new CipherUtilException(ex);
70         }
71         return Base64.encodeBase64String(addAll(iv, finalByte));
72     }
73
74     /**
75      * Decrypts the text using the secret key in key.properties file.
76      *
77      * @param message The encrypted string that must be decrypted using the ONAP Portal Encryption
78      *                Key
79      * @return The String decrypted
80      * @throws CipherUtilException if any decryption step fails
81      */
82
83     public static String decryptPKC(String message, String base64key) throws CipherUtilException {
84         byte[] encryptedMessage = Base64.decodeBase64(message);
85         Cipher cipher;
86         byte[] decrypted;
87         try {
88             cipher = Cipher.getInstance(ALGORITHM_DETAILS, CIPHER_PROVIDER);
89             byte[] initVector = Arrays.copyOfRange(encryptedMessage, 0, GCM_IV_LENGTH);
90             GCMParameterSpec spec =
91                 new GCMParameterSpec(GCM_TAG_LENGTH * java.lang.Byte.SIZE, initVector);
92             byte[] realData = subarray(encryptedMessage, GCM_IV_LENGTH, encryptedMessage.length);
93             cipher.init(Cipher.DECRYPT_MODE, getSecretKeySpec(base64key), spec);
94             decrypted = cipher.doFinal(realData);
95
96         } catch (Exception ex) {
97             log.error("decrypt failed", ex);
98             throw new CipherUtilException(ex);
99         }
100         return new String(decrypted);
101     }
102
103     private static SecretKeySpec getSecretKeySpec(String keyString) {
104         byte[] key = Base64.decodeBase64(keyString);
105         return new SecretKeySpec(key, ALGORITHM);
106     }
107
108     private static byte[] clone(byte[] array) {
109         return array == null ? null : array.clone();
110     }
111
112     private static byte[] addAll(byte[] array1, byte[] array2) {
113         if (array1 == null) {
114             return clone(array2);
115         } else if (array2 == null) {
116             return clone(array1);
117         } else {
118             byte[] joinedArray = new byte[array1.length + array2.length];
119             System.arraycopy(array1, 0, joinedArray, 0, array1.length);
120             System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
121             return joinedArray;
122         }
123     }
124
125     private static byte[] subarray(byte[] array, int startIndexInclusive, int endIndexExclusive) {
126         if (array == null) {
127             return new byte[0];
128         } else {
129             if (startIndexInclusive < 0) {
130                 startIndexInclusive = 0;
131             }
132
133             if (endIndexExclusive > array.length) {
134                 endIndexExclusive = array.length;
135             }
136
137             int newSize = endIndexExclusive - startIndexInclusive;
138             if (newSize <= 0) {
139                 return EMPTY_BYTE_ARRAY;
140             } else {
141                 byte[] subarray = new byte[newSize];
142                 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
143                 return subarray;
144             }
145         }
146     }
147 }