f42fc0111f946925ca73678bc728c8093a28a5e1
[so.git] / common / src / main / java / org / onap / so / utils / CryptoUtils.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (c) 2019 Samsung
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  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.utils;
24
25
26 import com.google.common.base.Strings;
27 import org.onap.so.logger.ErrorCode;
28 import org.onap.so.logger.MessageEnum;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31 import javax.crypto.Cipher;
32 import javax.crypto.spec.GCMParameterSpec;
33 import javax.crypto.spec.SecretKeySpec;
34 import java.security.GeneralSecurityException;
35 import java.security.SecureRandom;
36 import java.util.Arrays;
37
38
39 /**
40  * CryptoUtils adapted from RTTP client.
41  * 
42  */
43 public final class CryptoUtils {
44
45     private static final Logger logger = LoggerFactory.getLogger(CryptoUtils.class);
46
47
48     private static final String AES = "AES";
49     private static final String CLOUD_KEY = "aa3871669d893c7fb8abbcda31b88b4f";
50     private static final int GCM_TAG_LENGTH = 16;
51     private static final int GCM_IV_LENGTH = 12;
52     private static final String AES_GCM_NO_PADDING = "AES/GCM/NoPadding";
53
54     /**
55      * encrypt a value and generate a keyfile if the keyfile is not found then a new one is created
56      * 
57      * @throws GeneralSecurityException
58      */
59     public static String encrypt(String value, String keyString) throws GeneralSecurityException {
60         SecretKeySpec sks = getSecretKeySpec(keyString);
61         Cipher cipher = Cipher.getInstance(AES_GCM_NO_PADDING);
62         byte[] initVector = new byte[GCM_IV_LENGTH];
63         (new SecureRandom()).nextBytes(initVector);
64         GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH * java.lang.Byte.SIZE, initVector);
65         cipher.init(Cipher.ENCRYPT_MODE, sks, spec);
66         byte[] encoded = value.getBytes(java.nio.charset.StandardCharsets.UTF_8);
67         byte[] cipherText = new byte[initVector.length + cipher.getOutputSize(encoded.length)];
68         System.arraycopy(initVector, 0, cipherText, 0, initVector.length);
69         cipher.doFinal(encoded, 0, encoded.length, cipherText, initVector.length);
70         return byteArrayToHexString(cipherText);
71     }
72
73     /**
74      * decrypt a value
75      * 
76      * @throws GeneralSecurityException
77      */
78     public static String decrypt(String message, String keyString) throws GeneralSecurityException {
79         SecretKeySpec sks = getSecretKeySpec(keyString);
80         byte[] cipherText = hexStringToByteArray(message);
81         Cipher cipher = Cipher.getInstance(AES_GCM_NO_PADDING);
82         byte[] initVector = Arrays.copyOfRange(cipherText, 0, GCM_IV_LENGTH);
83         GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH * java.lang.Byte.SIZE, initVector);
84         cipher.init(Cipher.DECRYPT_MODE, sks, spec);
85         byte[] plaintext = cipher.doFinal(cipherText, GCM_IV_LENGTH, cipherText.length - GCM_IV_LENGTH);
86         return new String(plaintext);
87     }
88
89     public static String encryptCloudConfigPassword(String message) {
90         try {
91             return CryptoUtils.encrypt(message, CLOUD_KEY);
92         } catch (GeneralSecurityException e) {
93             logger.error(Strings.repeat("{} ", 3), MessageEnum.RA_GENERAL_EXCEPTION.toString(),
94                     ErrorCode.BusinessProcesssError.getValue(), "Exception in encryptPassword ", e);
95             return null;
96         }
97     }
98
99     public static String decryptCloudConfigPassword(String message) {
100         try {
101             return CryptoUtils.decrypt(message, CLOUD_KEY);
102         } catch (GeneralSecurityException e) {
103             logger.error(Strings.repeat("{} ", 3), MessageEnum.RA_GENERAL_EXCEPTION.toString(),
104                     ErrorCode.BusinessProcesssError.getValue(), "Exception in encryptPassword ", e);
105             return null;
106         }
107     }
108
109     private static SecretKeySpec getSecretKeySpec(String keyString) {
110         byte[] key = hexStringToByteArray(keyString);
111         return new SecretKeySpec(key, AES);
112     }
113
114     public static String byteArrayToHexString(byte[] b) {
115         StringBuilder sb = new StringBuilder(b.length * 2);
116         for (byte aB : b) {
117             int v = aB & 0xff;
118             if (v < 16) {
119                 sb.append('0');
120             }
121             sb.append(Integer.toHexString(v));
122         }
123         return sb.toString().toUpperCase();
124     }
125
126     private static byte[] hexStringToByteArray(String s) {
127         byte[] b = new byte[s.length() / 2];
128         for (int i = 0; i < b.length; i++) {
129             int index = i * 2;
130             int v = Integer.parseInt(s.substring(index, index + 2), 16);
131             b[i] = (byte) v;
132         }
133         return b;
134     }
135 }