Rework CryptoUtils
[clamp.git] / src / main / java / org / onap / clamp / clds / util / CryptoUtils.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP CLAMP
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                             reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END============================================
20  * ===================================================================
21  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  */
23
24 package org.onap.clamp.clds.util;
25
26 import com.att.eelf.configuration.EELFLogger;
27 import com.att.eelf.configuration.EELFManager;
28
29 import java.io.IOException;
30 import java.io.UnsupportedEncodingException;
31 import java.security.GeneralSecurityException;
32 import java.security.SecureRandom;
33 import java.util.Properties;
34
35 import javax.crypto.Cipher;
36 import javax.crypto.spec.IvParameterSpec;
37 import javax.crypto.spec.SecretKeySpec;
38
39 import org.apache.commons.codec.DecoderException;
40 import org.apache.commons.codec.binary.Hex;
41 import org.apache.commons.lang3.ArrayUtils;
42
43 /**
44  * CryptoUtils for encrypting/decrypting string based on a Key defined in
45  * application.properties (Spring config file).
46  * 
47  */
48 public final class CryptoUtils {
49     protected static final EELFLogger logger            = EELFManager.getInstance().getLogger(CryptoUtils.class);
50     // Openssl commands:
51     // Encrypt: echo -n "123456" | openssl aes-128-cbc -e -K <Private Hex key>
52     // -iv <16 Hex Bytes iv> | xxd -u -g100
53     // Final result is to put in properties file is: IV + Outcome of openssl
54     // command
55     // ************************************************************
56     // Decrypt: echo -n 'Encrypted string' | xxd -r -ps | openssl aes-128-cbc -d
57     // -K
58     // <Private Hex Key> -iv <16 Bytes IV extracted from Encrypted String>
59     private static final String       ALGORITHM         = "AES";
60     private static final String       ALGORYTHM_DETAILS = ALGORITHM + "/CBC/PKCS5PADDING";
61     private static final int          BLOCK_SIZE        = 128;
62     private static final String       KEY_PARAM         = "org.onap.clamp.encryption.aes.key";
63     private static SecretKeySpec      secretKeySpec     = null;
64     private IvParameterSpec           ivspec;
65     static {
66         Properties props = new Properties();
67         try {
68             props.load(ResourceFileUtil.getResourceAsStream("clds/key.properties"));
69             secretKeySpec = getSecretKeySpec(props.getProperty(KEY_PARAM));
70         } catch (IOException | DecoderException e) {
71             logger.error("Exception occurred during the key reading", e);
72         }
73     }
74
75     /**
76      * Encrypt a value based on the Clamp Encryption Key.
77      * 
78      * @param value
79      * @return The encrypted string
80      * @throws GeneralSecurityException
81      *             In case of issue with the encryption
82      * @throws UnsupportedEncodingException
83      *             In case of issue with the charset conversion
84      */
85     public String encrypt(String value) throws GeneralSecurityException, UnsupportedEncodingException {
86         Cipher cipher = Cipher.getInstance(CryptoUtils.ALGORYTHM_DETAILS, "SunJCE");
87         SecureRandom r = SecureRandom.getInstance("SHA1PRNG");
88         byte[] iv = new byte[BLOCK_SIZE / 8];
89         r.nextBytes(iv);
90         ivspec = new IvParameterSpec(iv);
91         cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivspec);
92         return Hex.encodeHexString(ArrayUtils.addAll(iv, cipher.doFinal(value.getBytes("UTF-8"))));
93     }
94
95     /**
96      * Decrypt a value based on the Clamp Encryption Key
97      * 
98      * @param message
99      *            The encrypted string that must be decrypted using the Clamp
100      *            Encryption Key
101      * @return The String decrypted
102      * @throws GeneralSecurityException
103      *             In case of issue with the encryption
104      * @throws DecoderException
105      *             In case of issue to decode the HexString
106      */
107     public String decrypt(String message) throws GeneralSecurityException, DecoderException {
108         byte[] encryptedMessage = Hex.decodeHex(message.toCharArray());
109         Cipher cipher = Cipher.getInstance(CryptoUtils.ALGORYTHM_DETAILS, "SunJCE");
110         ivspec = new IvParameterSpec(ArrayUtils.subarray(encryptedMessage, 0, BLOCK_SIZE / 8));
111         byte[] realData = ArrayUtils.subarray(encryptedMessage, BLOCK_SIZE / 8, encryptedMessage.length);
112         cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivspec);
113         byte[] decrypted = cipher.doFinal(realData);
114         return new String(decrypted);
115     }
116
117     private static SecretKeySpec getSecretKeySpec(String keyString) throws DecoderException {
118         byte[] key = Hex.decodeHex(keyString.toCharArray());
119         return new SecretKeySpec(key, CryptoUtils.ALGORITHM);
120     }
121 }