From a3cd1553531d81ca88b4d2f426fe527dd1e909a8 Mon Sep 17 00:00:00 2001 From: "Thomas Nelson Jr (arthurdent3) tn1381@att.com" Date: Mon, 8 Oct 2018 14:29:46 -0400 Subject: Update to support Encrypted password in properties. Update duplicate entries in pom file. Add dependency Fix Version Change-Id: If427601841c14cb14232452b4ec8236e76075275 Issue-ID: MUSIC-146 Signed-off-by: Thomas Nelson Jr (arthurdent3) tn1381@att.com --- jar/pom.xml | 36 ++- .../main/java/org/onap/music/main/CipherUtil.java | 269 +++++++++++++++++++++ .../main/java/org/onap/music/main/MusicUtil.java | 28 ++- 3 files changed, 316 insertions(+), 17 deletions(-) create mode 100644 jar/src/main/java/org/onap/music/main/CipherUtil.java diff --git a/jar/pom.xml b/jar/pom.xml index e5b9d802..9fc8ff30 100644 --- a/jar/pom.xml +++ b/jar/pom.xml @@ -1,4 +1,3 @@ - - +--> + 4.0.0 org.onap.music MUSIC jar - 2.5.6 + 2.5.7 This is the MUSIC REST interface, packaged as a war file. @@ -33,8 +33,8 @@ org.onap.oparent oparent - 1.2.0 - + 0.1.1 + @@ -185,6 +185,7 @@ provided + ch.qos.logback @@ -214,6 +215,7 @@ 1.0.1-oss + com.datastax.cassandra @@ -221,6 +223,7 @@ ${cassandra.version} + org.apache.zookeeper @@ -234,6 +237,7 @@ + com.sun.jersey @@ -327,12 +331,26 @@ com.google.guava guava + 19.0 org.mindrot jbcrypt 0.4 + + + commons-codec + commons-codec + 1.9 + + + + org.apache.commons + commons-lang3 + 3.0 + + diff --git a/jar/src/main/java/org/onap/music/main/CipherUtil.java b/jar/src/main/java/org/onap/music/main/CipherUtil.java new file mode 100644 index 00000000..1c7a687b --- /dev/null +++ b/jar/src/main/java/org/onap/music/main/CipherUtil.java @@ -0,0 +1,269 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============LICENSE_END============================================= + * ==================================================================== + */ +package org.onap.music.main; + +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.UnsupportedEncodingException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Scanner; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.ArrayUtils; +import org.onap.music.eelf.logging.EELFLoggerDelegate; + +public class CipherUtil { + + + /** + * Default key. + */ + private static String keyString = null; + + private static final String ALGORITHM = "AES"; + private static final String ALGORYTHM_DETAILS = ALGORITHM + "/CBC/PKCS5PADDING"; + private static final int BLOCK_SIZE = 128; + @SuppressWarnings("unused") + private static SecretKeySpec secretKeySpec; + private static IvParameterSpec ivspec; + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(CipherUtil.class); + /** + * @deprecated Please use {@link #encryptPKC(String)} to encrypt the text. + * + * Encrypts the text using the specified secret key. + * + * @param plainText + * Text to encrypt + * @param secretKey + * Key to use for encryption + * @return encrypted version of plain text. + * @ + * if any encryption step fails + * + */ + @Deprecated + public static String encrypt(String plainText, String secretKey) { + String encryptedString = null; + try { + byte[] encryptText = plainText.getBytes("UTF-8"); + byte[] rawKey = Base64.decodeBase64(secretKey); + SecretKeySpec sKeySpec = new SecretKeySpec(rawKey, "AES"); + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.ENCRYPT_MODE, sKeySpec); + encryptedString = Base64.encodeBase64String(cipher.doFinal(encryptText)); + } catch (BadPaddingException | IllegalBlockSizeException | InvalidKeyException | NoSuchAlgorithmException + | NoSuchPaddingException | UnsupportedEncodingException ex) { + } + return encryptedString; + } + + /** + * @deprecated Please use {@link #encryptPKC(String)} to encrypt the text. + * Encrypts the text using the secret key in key.properties file. + * + * @param plainText + * Text to encrypt + * @return Encrypted Text + * @ + * if any decryption step fails + */ + @Deprecated + public static String encrypt(String plainText) { + return CipherUtil.encrypt(plainText, keyString); + } + + /** + * Encrypts the text using a secret key. + * + * @param plainText + * Text to encrypt + * @return Encrypted Text + * @ + * if any decryption step fails + */ + public static String encryptPKC(String plainText) { + return CipherUtil.encryptPKC(plainText, keyString); + } + + /** + * + * @deprecated Please use {@link #decryptPKC(String)} to Decryption the text. + * + * Decrypts the text using the specified secret key. + * + * @param encryptedText + * Text to decrypt + * @param secretKey + * Key to use for decryption + * @return plain text version of encrypted text + * @ + * if any decryption step fails + * + */ + @Deprecated + public static String decrypt(String encryptedText, String secretKey) { + String encryptedString = null; + try { + byte[] rawKey = Base64.decodeBase64(secretKey); + SecretKeySpec sKeySpec = new SecretKeySpec(rawKey, "AES"); + byte[] encryptText = Base64.decodeBase64(encryptedText.getBytes("UTF-8")); + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.DECRYPT_MODE, sKeySpec); + encryptedString = new String(cipher.doFinal(encryptText)); + } catch (BadPaddingException | IllegalBlockSizeException | InvalidKeyException | NoSuchAlgorithmException + | NoSuchPaddingException | UnsupportedEncodingException ex) { + } + return encryptedString; + } + + private static SecretKeySpec getSecretKeySpec() { + byte[] key = Base64.decodeBase64(keyString); + return new SecretKeySpec(key, ALGORITHM); + } + + private static SecretKeySpec getSecretKeySpec(String keyString) { + byte[] key = Base64.decodeBase64(keyString); + return new SecretKeySpec(key, ALGORITHM); + } + + /** + * Encrypt the text using the secret key in key.properties file + * + * @param value + * @return The encrypted string + * @throws BadPaddingException + * @ + * In case of issue with the encryption + */ + public static String encryptPKC(String value, String skey) { + Cipher cipher = null; + byte[] iv = null, finalByte = null; + + try { + cipher = Cipher.getInstance(ALGORYTHM_DETAILS, "SunJCE"); + + SecureRandom r = SecureRandom.getInstance("SHA1PRNG"); + iv = new byte[BLOCK_SIZE / 8]; + r.nextBytes(iv); + ivspec = new IvParameterSpec(iv); + cipher.init(Cipher.ENCRYPT_MODE, getSecretKeySpec(skey), ivspec); + finalByte = cipher.doFinal(value.getBytes()); + + } catch (Exception ex) { + + } + return Base64.encodeBase64String(ArrayUtils.addAll(iv, finalByte)); + } + + /** + * Decrypts the text using the secret key in key.properties file. + * + * @param message + * The encrypted string that must be decrypted using the ecomp + * Encryption Key + * @return The String decrypted + * @ + * if any decryption step fails + */ + public static String decryptPKC(String message, String skey) { + byte[] encryptedMessage = Base64.decodeBase64(message); + Cipher cipher; + byte[] decrypted = null; + try { + cipher = Cipher.getInstance(ALGORYTHM_DETAILS, "SunJCE"); + ivspec = new IvParameterSpec(ArrayUtils.subarray(encryptedMessage, 0, BLOCK_SIZE / 8)); + byte[] realData = ArrayUtils.subarray(encryptedMessage, BLOCK_SIZE / 8, encryptedMessage.length); + cipher.init(Cipher.DECRYPT_MODE, getSecretKeySpec(skey), ivspec); + decrypted = cipher.doFinal(realData); + + } catch (Exception ex) { + + + } + + return new String(decrypted); + } + + /** + * @deprecated Please use {@link #decryptPKC(String)} to Decrypt the text. + * + * Decrypts the text using the secret key in key.properties file. + * + * @param encryptedText + * Text to decrypt + * @return Decrypted text + * @ + * if any decryption step fails + */ + @Deprecated + public static String decrypt(String encryptedText) { + return CipherUtil.decrypt(encryptedText, keyString); + } + + /** + * + * Decrypts the text using the secret key in key.properties file. + * + * @param encryptedText + * Text to decrypt + * @return Decrypted text + * @ + * if any decryption step fails + */ + public static String decryptPKC(String encryptedText) { + return CipherUtil.decryptPKC(encryptedText, keyString); + } + + + public static void readAndSetKeyString() { + try { + Scanner in = new Scanner(new FileReader("/opt/app/music/etc/properties.txt")); + StringBuilder sb = new StringBuilder(); + while(in.hasNext()) { + sb.append(in.next()); + } + in.close(); + keyString = sb.toString(); + } catch (FileNotFoundException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage()); + } + } + + /*public static void main(String[] args) { + + System.out.println("Encrypted password: "+encryptPKC("cassandra")); + + System.out.println("Decrypted password: "+decryptPKC("dDhqAp5/RwZbl9yRSZg15fN7Qul9eiE/JFkKemtTib0=")); + System.out.println("Decrypted password: "+decryptPKC("I/dOtD/YYzBStbtOYhKuUUyPHSW2G9ZzdSyB8bJp4vk=")); + System.out.println("Decrypted password: "+decryptPKC("g7zJqg74dLsH/fyL7I75b4eySy3pbMS2xVqkrB5lDl8=")); + }*/ + +} diff --git a/jar/src/main/java/org/onap/music/main/MusicUtil.java b/jar/src/main/java/org/onap/music/main/MusicUtil.java index f18570db..77afb57e 100755 --- a/jar/src/main/java/org/onap/music/main/MusicUtil.java +++ b/jar/src/main/java/org/onap/music/main/MusicUtil.java @@ -531,14 +531,15 @@ public class MusicUtil { public static void loadProperties() throws Exception { - Properties prop = new Properties(); + CipherUtil.readAndSetKeyString(); + Properties prop = new Properties(); InputStream input = null; try { - // load the properties file + // load the properties file input = MusicUtil.class.getClassLoader().getResourceAsStream("music.properties"); prop.load(input); } catch (Exception ex) { - logger.error(EELFLoggerDelegate.errorLogger, "Unable to find properties file."); + logger.error(EELFLoggerDelegate.errorLogger, "Unable to find properties file."); throw new Exception(); } finally { if (input != null) { @@ -549,12 +550,23 @@ public class MusicUtil { } } } + String cassPwd = prop.getProperty("cassandra.password"); + String isEncrypted = prop.getProperty("cassandra.password.isencrypted"); + logger.info(EELFLoggerDelegate.applicationLogger,"cassandra.password:" + cassPwd); + logger.info(EELFLoggerDelegate.applicationLogger,"cassandra.password.isencrypted:" + isEncrypted); + if("true".equals(isEncrypted)) { + logger.info(EELFLoggerDelegate.applicationLogger,"Decrypting...."); + cassPwd = CipherUtil.decryptPKC(cassPwd); + logger.info(EELFLoggerDelegate.applicationLogger,"Decrypted password: "+cassPwd); + MusicUtil.setCassPwd(cassPwd); + } else + MusicUtil.setCassPwd(cassPwd); // get the property value and return it - MusicUtil.setMyCassaHost(prop.getProperty("cassandra.host")); - String zkHosts = prop.getProperty("zookeeper.host"); - MusicUtil.setMyZkHost(zkHosts); - MusicUtil.setCassName(prop.getProperty("cassandra.user")); - MusicUtil.setCassPwd(prop.getProperty("cassandra.password")); + MusicUtil.setMyCassaHost(prop.getProperty("cassandra.host")); + String zkHosts = prop.getProperty("zookeeper.host"); + MusicUtil.setMyZkHost(zkHosts); + MusicUtil.setCassName(prop.getProperty("cassandra.user")); } + } -- cgit 1.2.3-korg