1 package org.openecomp.sdc.security;
3 import org.slf4j.Logger;
4 import org.slf4j.LoggerFactory;
5 import javax.crypto.BadPaddingException;
6 import javax.crypto.Cipher;
7 import javax.crypto.IllegalBlockSizeException;
8 import javax.crypto.NoSuchPaddingException;
9 import javax.crypto.spec.SecretKeySpec;
10 import java.io.UnsupportedEncodingException;
11 import java.nio.charset.StandardCharsets;
12 import java.security.InvalidKeyException;
13 import java.security.Key;
14 import java.security.NoSuchAlgorithmException;
15 import java.util.Base64;
18 public class SecurityUtil {
20 private static final Logger LOG = LoggerFactory.getLogger( SecurityUtil.class );
21 private static final byte[] KEY = new byte[]{-64,5,-32 ,-117 ,-44,8,-39, 1, -9, 36,-46,-81, 62,-15,-63,-75};
22 public static final SecurityUtil INSTANCE = new SecurityUtil();
23 public static final String ALGORITHM = "AES" ;
24 public static final String CHARSET = StandardCharsets.UTF_8.name();
26 public static Key secKey = null ;
30 * cmd commands >$PROGRAM_NAME decrypt "$ENCRYPTED_MSG"
31 * >$PROGRAM_NAME encrypt "message"
33 public static void main(String[] args) throws Exception {
34 if ( args!=null && args.length>1){
35 fj.data.Either res = null;
36 final String op = args[0].trim().toLowerCase();
40 res = INSTANCE.decrypt(Base64.getDecoder().decode(args[1]), true);
43 res = INSTANCE.encrypt(args[1]);
46 LOG.warn("Unfamiliar command please use: \n>aes <encrypt/decrypt> 'message to encrypt/decrypt' ");
49 LOG.debug( "cannot perform {}:" );
52 LOG.debug( "output: {}", res!=null && res.isLeft() ? res.left().value() : "ERROR" );
56 private SecurityUtil(){ super(); }
60 secKey = generateKey( KEY, ALGORITHM );
63 LOG.warn("cannot generate key for {}", ALGORITHM);
69 public static Key generateKey(final byte[] KEY, String algorithm){
70 return new SecretKeySpec(KEY, algorithm);
73 //obfuscates key prefix -> **********
74 public String obfuscateKey(String sensitiveData){
76 if (sensitiveData != null){
77 int len = sensitiveData.length();
78 StringBuilder builder = new StringBuilder(sensitiveData);
79 for (int i=0; i<len/2; i++){
80 builder.setCharAt(i, '*');
82 return builder.toString();
88 * @param strDataToEncrypt - plain string to encrypt
90 * a. Declare / Initialize the Data. Here the data is of type String
91 * b. Convert the Input Text to Bytes
92 * c. Encrypt the bytes using doFinal method
94 public Either<String,String> encrypt(String strDataToEncrypt){
95 if (strDataToEncrypt != null ){
97 LOG.debug("Encrypt key -> {}", secKey);
98 Cipher aesCipherForEncryption = Cipher.getInstance("AES"); // Must specify the mode explicitly as most JCE providers default to ECB mode!!
99 aesCipherForEncryption.init(Cipher.ENCRYPT_MODE, secKey);
100 byte[] byteDataToEncrypt = strDataToEncrypt.getBytes();
101 byte[] byteCipherText = aesCipherForEncryption.doFinal(byteDataToEncrypt);
102 String strCipherText = new String( java.util.Base64.getMimeEncoder().encode(byteCipherText), CHARSET );
103 LOG.debug("Cipher Text generated using AES is {}", strCipherText);
104 return Either.left(strCipherText);
105 } catch( NoSuchAlgorithmException | UnsupportedEncodingException e){
106 LOG.warn( "cannot encrypt data unknown algorithm or missing encoding for {}" ,secKey.getAlgorithm());
107 } catch( InvalidKeyException e){
108 LOG.warn( "invalid key recieved - > {} | {}" , java.util.Base64.getDecoder().decode( secKey.getEncoded() ), e.getMessage() );
109 } catch( IllegalBlockSizeException | BadPaddingException | NoSuchPaddingException e){
110 LOG.warn( "bad algorithm definition (Illegal Block Size or padding), please review you algorithm block&padding" , e.getMessage() );
113 return Either.right("Cannot encrypt "+strDataToEncrypt);
118 * @param byteCipherText - should be valid bae64 input in the length of 16bytes
119 * @param isBase64Decoded - is data already base64 encoded&aligned to 16 bytes
120 * a. Initialize a new instance of Cipher for Decryption (normally don't reuse the same object)
121 * b. Decrypt the cipher bytes using doFinal method
123 public Either<String,String> decrypt(byte[] byteCipherText , boolean isBase64Decoded){
124 if (byteCipherText != null){
125 byte[] alignedCipherText = byteCipherText;
128 alignedCipherText = Base64.getDecoder().decode(byteCipherText);
129 LOG.debug("Decrypt key -> "+secKey.getEncoded());
130 Cipher aesCipherForDecryption = Cipher.getInstance("AES"); // Must specify the mode explicitly as most JCE providers default to ECB mode!!
131 aesCipherForDecryption.init(Cipher.DECRYPT_MODE, secKey);
132 byte[] byteDecryptedText = aesCipherForDecryption.doFinal(alignedCipherText);
133 String strDecryptedText = new String(byteDecryptedText);
134 LOG.debug("Decrypted Text message is: {}" , obfuscateKey( strDecryptedText ));
135 return Either.left(strDecryptedText);
136 } catch( NoSuchAlgorithmException e){
137 LOG.warn( "cannot encrypt data unknown algorithm or missing encoding for {}" ,secKey.getAlgorithm());
138 } catch( InvalidKeyException e){
139 LOG.warn( "invalid key recieved - > {} | {}" , java.util.Base64.getDecoder().decode( secKey.getEncoded() ), e.getMessage() );
140 } catch( IllegalBlockSizeException | BadPaddingException | NoSuchPaddingException e){
141 LOG.warn( "bad algorithm definition (Illegal Block Size or padding), please review you algorithm block&padding" , e.getMessage() );
144 return Either.right("Decrypt FAILED");
147 public Either<String,String> decrypt(String byteCipherText){
149 return decrypt(byteCipherText.getBytes(CHARSET),true);
150 } catch( UnsupportedEncodingException e ){
151 LOG.warn( "Missing encoding for {} | {} " ,secKey.getAlgorithm() , e.getMessage());
153 return Either.right("Decrypt FAILED");