From c1b69dfb1297365d35f2ada8690f13f787d38b4f Mon Sep 17 00:00:00 2001 From: pa834y Date: Tue, 26 Mar 2019 14:29:38 -0400 Subject: Enhancement to use the common CryptoUtils Change-Id: I06718526382b424eab991f39a7dac1b5cf4f1b74 Issue-ID: POLICY-1422 Signed-off-by: pa834y --- .../java/org/onap/policy/utils/CryptoUtils.java | 256 --------------------- .../java/org/onap/policy/utils/PeCryptoUtils.java | 102 ++++++++ .../org/onap/policy/utils/PeCryptoUtilsTest.java | 64 ++++++ .../onap/policy/utils/test/CryptoUtilsTest.java | 128 ----------- 4 files changed, 166 insertions(+), 384 deletions(-) delete mode 100644 PolicyEngineUtils/src/main/java/org/onap/policy/utils/CryptoUtils.java create mode 100644 PolicyEngineUtils/src/main/java/org/onap/policy/utils/PeCryptoUtils.java create mode 100644 PolicyEngineUtils/src/test/java/org/onap/policy/utils/PeCryptoUtilsTest.java delete mode 100644 PolicyEngineUtils/src/test/java/org/onap/policy/utils/test/CryptoUtilsTest.java (limited to 'PolicyEngineUtils') diff --git a/PolicyEngineUtils/src/main/java/org/onap/policy/utils/CryptoUtils.java b/PolicyEngineUtils/src/main/java/org/onap/policy/utils/CryptoUtils.java deleted file mode 100644 index 15a93bdab..000000000 --- a/PolicyEngineUtils/src/main/java/org/onap/policy/utils/CryptoUtils.java +++ /dev/null @@ -1,256 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * PolicyEngineUtils - * ================================================================================ - * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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.policy.utils; - -import java.nio.charset.StandardCharsets; -import java.security.AlgorithmParameters; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.Key; -import java.util.Base64; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.spec.SecretKeySpec; -import javax.xml.bind.DatatypeConverter; - -import org.onap.policy.common.logging.flexlogger.FlexLogger; -import org.onap.policy.common.logging.flexlogger.Logger; - -public class CryptoUtils { - private static final Logger LOGGER = FlexLogger.getLogger(CryptoUtils.class); - private static final String CIPHER_TYPE = "AES/CBC/PKCS5Padding"; - private static Key mKey = null; - private static AlgorithmParameters mAlgParm = null; - - static { - //the hadcoded key is to be removed in a future iteration - try { - String kval = "bmpybWJrbGN4dG9wbGF3Zg=="; - String algp = "BBBpbml0VmVjVGhpc0lzVGhl"; - - byte[] kvalb = DatatypeConverter.parseBase64Binary(kval); - byte[] algb = DatatypeConverter.parseBase64Binary(algp); - - mKey = new SecretKeySpec(kvalb, "AES"); - - mAlgParm = AlgorithmParameters.getInstance("AES"); - mAlgParm.init(algb, "ASN.1"); - - } catch (Exception ex) { - throw new ExceptionInInitializerError(ex); - } - } - - private CryptoUtils() { - // Private Constructor - } - - /** - * Decrypt txt. - * - * @param encryptedTxt - * text to be decrypted, Base 64 UrlEncoded - * @return the byte[] - * @throws NoSuchAlgorithmException - * the no such algorithm exception - * @throws NoSuchPaddingException - * the no such padding exception - * @throws InvalidAlgorithmParameterException - * the invalid algorithm parameter exception - * @throws InvalidKeyException - * the invalid key exception - * @throws IllegalBlockSizeException - * the illegal block size exception - * @throws BadPaddingException - * the bad padding exception - */ - public static byte[] decryptTxt(String encryptedTxt) - throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, - InvalidKeyException, IllegalBlockSizeException, BadPaddingException { - Cipher cipher = Cipher.getInstance(CIPHER_TYPE); - cipher.init(Cipher.DECRYPT_MODE, mKey, mAlgParm); - - return cipher.doFinal(Base64.getUrlDecoder().decode(encryptedTxt.getBytes(StandardCharsets.UTF_8))); - } - - /** - * Decrypt txt. - * - * @param encryptedTxt - * text to be decrypted, Base 64 UrlEncoded - * @param mKey - * the key as Base 64 - * @return the byte[] - * @throws NoSuchAlgorithmException - * the no such algorithm exception - * @throws NoSuchPaddingException - * the no such padding exception - * @throws InvalidAlgorithmParameterException - * the invalid algorithm parameter exception - * @throws InvalidKeyException - * the invalid key exception - * @throws IllegalBlockSizeException - * the illegal block size exception - * @throws BadPaddingException - * the bad padding exception - */ - public static byte[] decryptTxt(String encryptedTxt, String base64BinaryKey) - throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, - InvalidKeyException, IllegalBlockSizeException, BadPaddingException { - - byte[] keyValueByte = DatatypeConverter.parseBase64Binary(base64BinaryKey); - Key paramKey = new SecretKeySpec(keyValueByte, "AES"); - Cipher cipher = Cipher.getInstance(CIPHER_TYPE); - cipher.init(Cipher.DECRYPT_MODE, paramKey, mAlgParm); - - return cipher.doFinal(Base64.getUrlDecoder().decode(encryptedTxt.getBytes(StandardCharsets.UTF_8))); - } - - /** - * Decrypt txt, no exceptions thrown. - * - * @param encryptedTxt - * text to be decrypted, Base 64 UrlEncoded - * @return the decrypted text, or the original text if it could not be - * decrypted - */ - public static byte[] decryptTxtNoEx(String encryptedTxt) { - - try { - if (encryptedTxt == null || encryptedTxt.isEmpty()) { - LOGGER.info("decryptTxtNoEx: Input param encryptedTxt is empty"); - return new byte[0]; - } - return decryptTxt(encryptedTxt); - } catch (Exception e) { - try { - LOGGER.info("decryptTxtNoEx: Exception while decrypting : " + e); - return (encryptedTxt != null) ? encryptedTxt.getBytes(StandardCharsets.UTF_8) : new byte[0]; - } catch (Exception e1) { - LOGGER.warn("decryptTxtNoEx: Exception on sending default : " + e1); - return new byte[0]; - } - } - } - - /** - * Decrypt txt, no exceptions thrown. - * - * @param encryptedTxt - * text to be decrypted, Base 64 UrlEncoded - * @return the decrypted text, or the original text if it could not be - * decrypted - */ - public static String decryptTxtNoExStr(String encryptedTxt) { - return new String(decryptTxtNoEx(encryptedTxt), StandardCharsets.UTF_8); - } - - /** - * Encrypt txt. - * - * @param plainTxt - * the plain txt - * @return the encrypted string - * @throws NoSuchPaddingException - * the no such padding exception - * @throws InvalidAlgorithmParameterException - * the invalid algorithm parameter exception - * @throws NoSuchAlgorithmException - * the no such algorithm exception - * @throws InvalidKeyException - * the invalid key exception - * @throws IllegalBlockSizeException - * the illegal block size exception - * @throws BadPaddingException - * the bad padding exception - */ - public static String encryptTxt(byte[] plainTxt) - throws NoSuchPaddingException, InvalidAlgorithmParameterException, - NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { - - Cipher cipher = Cipher.getInstance(CIPHER_TYPE); - cipher.init(Cipher.ENCRYPT_MODE, mKey, mAlgParm); - - byte[] encryption = cipher.doFinal(plainTxt); - return new String(Base64.getUrlEncoder().encode(encryption), StandardCharsets.UTF_8); - } - - /** - * Encrypt txt. - * - * @param plainTxt - * the plain txt to be encrypted - * @param base64BinaryKey - * the key as lexical representation of Base64 Binary - * @return the encrypted string - * @throws NoSuchPaddingException - * the no such padding exception - * @throws InvalidAlgorithmParameterException - * the invalid algorithm parameter exception - * @throws NoSuchAlgorithmException - * the no such algorithm exception - * @throws InvalidKeyException - * the invalid key exception - * @throws IllegalBlockSizeException - * the illegal block size exception - * @throws BadPaddingException - * the bad padding exception - */ - public static String encryptTxt(byte[] plainTxt, String base64BinaryKey) - throws NoSuchPaddingException, InvalidAlgorithmParameterException, - NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { - - byte[] keyValueByte = DatatypeConverter.parseBase64Binary(base64BinaryKey); - Key paramKey = new SecretKeySpec(keyValueByte, "AES"); - Cipher cipher = Cipher.getInstance(CIPHER_TYPE); - cipher.init(Cipher.ENCRYPT_MODE, paramKey, mAlgParm); - - byte[] encryption = cipher.doFinal(plainTxt); - return new String(Base64.getMimeEncoder().encode(encryption), StandardCharsets.UTF_8); - } - - /** - * Encrypt txt, no exceptions thrown - * - * @param plainTxt - * the plain txt to be encrypted - * @return the encrypted String , or the original text if it could not be - * encrypted - */ - public static String encryptTxtNoEx(byte[] plainTxt) { - - if (plainTxt == null || plainTxt.length == 0) { - LOGGER.error("encryptTxtNoEx: Input param plainTxt is not valid"); - return ""; - } - - try { - return encryptTxt(plainTxt); - } catch (Exception e) { - LOGGER.error("encryptTxtNoEx: Exception while decryption : " + e); - return new String(plainTxt, StandardCharsets.UTF_8); - } - } - -} \ No newline at end of file diff --git a/PolicyEngineUtils/src/main/java/org/onap/policy/utils/PeCryptoUtils.java b/PolicyEngineUtils/src/main/java/org/onap/policy/utils/PeCryptoUtils.java new file mode 100644 index 000000000..9863f03ad --- /dev/null +++ b/PolicyEngineUtils/src/main/java/org/onap/policy/utils/PeCryptoUtils.java @@ -0,0 +1,102 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP Policy Engine + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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.policy.utils; + +import java.security.GeneralSecurityException; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import org.apache.commons.lang3.StringUtils; +import org.onap.policy.common.logging.flexlogger.FlexLogger; +import org.onap.policy.common.logging.flexlogger.Logger; +import org.onap.policy.common.utils.security.CryptoUtils; + +public class PeCryptoUtils { + + private static Logger logger = FlexLogger.getLogger(PeCryptoUtils.class); + private static final String PROP_AES_KEY = "org.onap.policy.encryption.aes.key"; + private static CryptoUtils cryptoUtils = null; + private static String secretKey = System.getenv("AES_ENCRYPTION_KEY"); + private static final Map decryptCache = new ConcurrentHashMap<>(); + private static final Map encryptCache = new ConcurrentHashMap<>(); + + + private PeCryptoUtils() {} + + /** + * Inits the aes key. + * + * @param theSecretKey the the secret key + */ + public static synchronized void initAesKey(String theSecretKey) { + String secKey = theSecretKey; + if (cryptoUtils == null) { + if (StringUtils.isBlank(secKey)) { + secKey = System.getProperty(PROP_AES_KEY); + } + if (StringUtils.isBlank(secKey)) { + secKey = secretKey; + } + cryptoUtils = new CryptoUtils(secKey); + } + } + + /** + * Encrypt a value based on the Policy Encryption Key. + * + * @param value The plain text string + * @return The encrypted String + */ + public static String encrypt(String value) { + + if (cryptoUtils == null || StringUtils.isBlank(value)) { + return value; + } + + return encryptCache.computeIfAbsent(value, k -> { + try { + return cryptoUtils.encrypt(k); + } catch (GeneralSecurityException e) { + logger.error("Could not decrypt value - exception: ", e); + return value; + } + }); + } + + /** + * Decrypt a value based on the Policy Encryption Key if string begin with 'enc:'. + * + * @param value The encrypted string that must be decrypted using the Policy Encryption Key + * @return The String decrypted if string begin with 'enc:' + */ + public static String decrypt(String value) { + if (cryptoUtils == null || StringUtils.isBlank(value)) { + return value; + } + return decryptCache.computeIfAbsent(value, k -> { + try { + return cryptoUtils.decrypt(k); + } catch (GeneralSecurityException e) { + logger.error("Could not decrypt value - exception: ", e); + return value; + } + }); + } +} diff --git a/PolicyEngineUtils/src/test/java/org/onap/policy/utils/PeCryptoUtilsTest.java b/PolicyEngineUtils/src/test/java/org/onap/policy/utils/PeCryptoUtilsTest.java new file mode 100644 index 000000000..3765ff2e3 --- /dev/null +++ b/PolicyEngineUtils/src/test/java/org/onap/policy/utils/PeCryptoUtilsTest.java @@ -0,0 +1,64 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP-REST + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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.policy.utils; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import java.security.GeneralSecurityException; +import org.junit.Before; +import org.junit.Test; +import org.powermock.reflect.Whitebox; + + +public class PeCryptoUtilsTest { + private final String pass = "policy_user"; + private final String secretKey = "bmpybWJrbGN4dG9wbGF3Zg=="; + private final String encryptedPass = "enc:5ID9PoqWIzBaut+KQcAFBtci9CKDRcCNRHRjdBnXM5U="; + private static final String PROP_AES_KEY = "org.onap.policy.encryption.aes.key"; + + @Before + public void reset() { + Whitebox.setInternalState( PeCryptoUtils.class, "cryptoUtils", (PeCryptoUtils)null); + + } + + @Test + public void testEncrypt() throws GeneralSecurityException { + assertEquals(pass, PeCryptoUtils.encrypt(pass)); + PeCryptoUtils.initAesKey(secretKey); + System.out.println("original value : " + pass + " encrypted value: " + PeCryptoUtils.encrypt(pass)); + assertNotNull(PeCryptoUtils.encrypt(pass)); + } + + @Test + public void testDecrypt() throws Exception { + assertEquals(pass, PeCryptoUtils.decrypt(pass)); + System.setProperty(PROP_AES_KEY, secretKey); + PeCryptoUtils.initAesKey(null); + System.clearProperty(PROP_AES_KEY); + assertEquals(pass, PeCryptoUtils.decrypt(encryptedPass)); + Whitebox.setInternalState( PeCryptoUtils.class, "cryptoUtils", (PeCryptoUtils)null); + Whitebox.setInternalState( PeCryptoUtils.class, "secretKey", secretKey); + PeCryptoUtils.initAesKey(" "); + assertEquals(pass, PeCryptoUtils.decrypt(pass)); + } + +} diff --git a/PolicyEngineUtils/src/test/java/org/onap/policy/utils/test/CryptoUtilsTest.java b/PolicyEngineUtils/src/test/java/org/onap/policy/utils/test/CryptoUtilsTest.java deleted file mode 100644 index e2ca78a06..000000000 --- a/PolicyEngineUtils/src/test/java/org/onap/policy/utils/test/CryptoUtilsTest.java +++ /dev/null @@ -1,128 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * PolicyEngineUtils - * ================================================================================ - * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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.policy.utils.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertArrayEquals; - -import java.nio.charset.StandardCharsets; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; - -import javax.crypto.BadPaddingException; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; - -import org.junit.Test; -import org.onap.policy.utils.CryptoUtils; - -public class CryptoUtilsTest { - - @Test - public final void testDecryptTxt() throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, - InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException - { - String decryptedTxt = new String(CryptoUtils.decryptTxt("g0uHKXCLyzJ6wSbpphNGsA=="), StandardCharsets.UTF_8); - assertEquals("mypass", decryptedTxt); - } - - @Test - public final void testDecryptTxtWithKey() throws InvalidKeyException, NoSuchAlgorithmException, - NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException - { - String decryptedTxt = new String(CryptoUtils.decryptTxt("g0uHKXCLyzJ6wSbpphNGsA==", "bmpybWJrbGN4dG9wbGF3Zg=="), - StandardCharsets.UTF_8); - assertEquals("mypass", decryptedTxt); - } - - @Test - public final void testDecryptTxtNoEx() { - String decryptedTxt = new String(CryptoUtils.decryptTxtNoEx("g0uHKXCLyzJ6wSbpphNGsA=="), - StandardCharsets.UTF_8); - assertEquals("mypass", decryptedTxt); - - } - - @Test - public final void testDecryptTxtNoExStr() { - assertEquals("mypass", CryptoUtils.decryptTxtNoExStr("g0uHKXCLyzJ6wSbpphNGsA==")); - } - @Test - public final void testDecryptTxtNoExInvalidInput() { - assertArrayEquals(new byte[0], CryptoUtils.decryptTxtNoEx(null)); - assertArrayEquals(new byte[0], CryptoUtils.decryptTxtNoEx("")); - // ensure backward compatibility - assertEquals("bogus", new String(CryptoUtils.decryptTxtNoEx("bogus"), StandardCharsets.UTF_8)); - assertEquals("admin123", CryptoUtils.decryptTxtNoExStr("admin123")); - assertEquals("password", CryptoUtils.decryptTxtNoExStr("password")); - } - - @Test(expected = IllegalArgumentException.class) - public final void testDecryptTxtInvalidInput() throws InvalidKeyException, NoSuchAlgorithmException, - NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException - { - CryptoUtils.decryptTxt("bogus"); - } - - @Test - public final void testEncryptTxt() throws InvalidKeyException, NoSuchPaddingException, - InvalidAlgorithmParameterException, NoSuchAlgorithmException, IllegalBlockSizeException, - BadPaddingException { - String txtStr = "mypass"; - byte[] txt = txtStr.getBytes(StandardCharsets.UTF_8); - assertEquals("g0uHKXCLyzJ6wSbpphNGsA==", CryptoUtils.encryptTxt(txt)); - } - - @Test - public final void testEncryptTxtWithKey() throws InvalidKeyException, - NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, - IllegalBlockSizeException, BadPaddingException { - String txtStr = "mypass"; - byte[] txt = txtStr.getBytes(StandardCharsets.UTF_8); - assertEquals("g0uHKXCLyzJ6wSbpphNGsA==", CryptoUtils.encryptTxt(txt, "bmpybWJrbGN4dG9wbGF3Zg==")); - } - - @Test - public final void testEncryptTxtNoEx() { - String txtStr = "mypass"; - byte[] txt = txtStr.getBytes(StandardCharsets.UTF_8); - assertEquals("g0uHKXCLyzJ6wSbpphNGsA==", CryptoUtils.encryptTxtNoEx(txt)); - } - - @Test - public final void testEncryptTxtNoExInvalidInput() { - String txtStr = ""; - byte[] txt = txtStr.getBytes(StandardCharsets.UTF_8); - assertEquals("", CryptoUtils.encryptTxtNoEx(txt)); - assertEquals("", CryptoUtils.encryptTxtNoEx(null)); - } - - @Test(expected = InvalidKeyException.class) - public final void testEncryptTxtWithKeyInvalid() throws InvalidKeyException, - NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, - IllegalBlockSizeException, BadPaddingException { - String txtStr = "mypass"; - byte[] txt = txtStr.getBytes(StandardCharsets.UTF_8); - CryptoUtils.encryptTxt(txt, "mykey"); - } - - -} \ No newline at end of file -- cgit 1.2.3-korg