View Javadoc

1   /*
2    * Copyright (C) 2017-2019 Centre National d'Etudes Spatiales (CNES).
3    *
4    * This library is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Lesser General Public
6    * License as published by the Free Software Foundation; either
7    * version 3.0 of the License, or (at your option) any later version.
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   * Lesser General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this library; if not, write to the Free Software
16   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17   * MA 02110-1301  USA
18   */
19  package fr.cnes.doi.security;
20  
21  import fr.cnes.doi.exception.DoiRuntimeException;
22  import fr.cnes.doi.utils.Utils;
23  import java.io.UnsupportedEncodingException;
24  import java.nio.charset.StandardCharsets;
25  import java.security.InvalidKeyException;
26  import java.security.NoSuchAlgorithmException;
27  import java.util.Base64;
28  import javax.crypto.BadPaddingException;
29  import javax.crypto.Cipher;
30  import javax.crypto.IllegalBlockSizeException;
31  import javax.crypto.NoSuchPaddingException;
32  import javax.crypto.spec.SecretKeySpec;
33  import org.apache.logging.log4j.LogManager;
34  import org.apache.logging.log4j.Logger;
35  
36  /**
37   * Utility class to encrypt/decrypt
38   *
39   * @author Jean-Christophe Malapert (jean-christophe.malapert@cnes.fr)
40   */
41  public final class UtilsCryptography {
42  
43      /**
44       * Name of the transformation.
45       */
46      public static final String CIPHER_ALGORITHM = "AES";
47  
48      /**
49       * Name of the secret-key algorithm to be associated with the given key
50       * material.
51       */
52      public static final String KEY_ALGORITHM = CIPHER_ALGORITHM;
53  
54      /**
55       * Default key to encrypt/decrypt. The key is a 16 bits length key
56       */
57      public static final String DEFAULT_SECRET_KEY = "16BYTESSECRETKEY";
58  
59      /**
60       * Logger.
61       */
62      private static final Logger LOG = LogManager.getLogger(UtilsCryptography.class.getName());
63  
64      /**
65       * Template message.
66       */
67      private static final String MSG_TPL = "Parameter : {}";
68  
69      /**
70       * Template message.
71       */
72      private static final String MSG_TPL2 = "Parameters : {} and {}";
73  
74      /**
75       * Decrypts the string with the DEFAULT_SECRET_KEY.
76       *
77       * @param encryptedInput string to decrypt.
78       * @return the decrypted string
79       */
80      public static String decrypt(final String encryptedInput) {
81          LOG.traceEntry(MSG_TPL, encryptedInput);
82          return LOG.traceExit(decrypt(encryptedInput, DEFAULT_SECRET_KEY));
83      }
84  
85      /**
86       * Decrypts the string with a custom secret key.
87       *
88       * @param encryptedInput string to decrypt.
89       * @param secretKey the secret key.
90       * @return the decrypted string
91       */
92      public static String decrypt(final String encryptedInput,
93              final String secretKey) {
94          LOG.traceEntry(MSG_TPL2, encryptedInput, secretKey);
95          if (Utils.isNotEmpty(encryptedInput)) {
96              try {
97                  final Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
98                  cipher.init(
99                          Cipher.DECRYPT_MODE,
100                         new SecretKeySpec(
101                                 secretKey.getBytes(StandardCharsets.UTF_8),
102                                 KEY_ALGORITHM)
103                 );
104                 return LOG.traceExit(new String(
105                         cipher.doFinal(Base64.getDecoder().decode(encryptedInput)),
106                         StandardCharsets.UTF_8
107                 ));
108             } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex) {
109                 throw LOG.throwing(new DoiRuntimeException(ex));
110             }
111         } else {
112             throw LOG.throwing(new DoiRuntimeException("Cannot decrypt empty input"));
113         }
114     }
115 
116     /**
117      * Encrypts the string with the DEFAULT_SECRET_KEY.
118      *
119      * @param str string to encrypt
120      * @return the encrypted string.
121      */
122     public static String encrypt(final String str) {
123         LOG.traceEntry(MSG_TPL, str);
124         return LOG.traceExit(encrypt(str, DEFAULT_SECRET_KEY));
125     }
126 
127     /**
128      * Encrypts the string with a specific secret key.
129      *
130      * @param str string to encrypt
131      * @param secretKey the secret key of 16 bits length
132      * @return the decrypted string
133      */
134     public static String encrypt(final String str,
135             final String secretKey) {
136         LOG.traceEntry(MSG_TPL2, str, secretKey);
137         try {
138             final Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
139             cipher.init(Cipher.ENCRYPT_MODE,
140                     new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), KEY_ALGORITHM)
141             );
142             return LOG.traceExit(Base64.getEncoder().encodeToString(
143                     cipher.doFinal(str.getBytes("UTF-8"))
144             ));
145         } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | UnsupportedEncodingException | IllegalBlockSizeException | BadPaddingException ex) {
146             throw LOG.throwing(new DoiRuntimeException(ex));
147         }
148     }
149 
150     /**
151      * Private constructor
152      */
153     private UtilsCryptography() {
154         //not called
155     }
156 }