1 package be
.nikiroo
.utils
;
3 import java
.io
.IOException
;
4 import java
.io
.UnsupportedEncodingException
;
5 import java
.security
.InvalidKeyException
;
6 import java
.security
.NoSuchAlgorithmException
;
8 import javax
.crypto
.BadPaddingException
;
9 import javax
.crypto
.Cipher
;
10 import javax
.crypto
.IllegalBlockSizeException
;
11 import javax
.crypto
.NoSuchPaddingException
;
12 import javax
.crypto
.SecretKey
;
13 import javax
.crypto
.spec
.SecretKeySpec
;
14 import javax
.net
.ssl
.SSLException
;
17 * Small utility class to do AES encryption/decryption.
19 * Do not assume it is actually secure until you checked the code...
23 public class CryptUtils
{
24 private Cipher ecipher
;
25 private Cipher dcipher
;
28 * Small and leazy way to initialize a 128 bits key with {@link CryptUtils}.
30 * <b>Some</b> part of the key will be used to generate a 128 bits key and
31 * initialize the {@link CryptUtils}; even NULL will generate something.
33 * <b>This is most probably not secure. Do not use if you actually care
37 * the {@link String} to use as a base for the key, can be NULL
39 public CryptUtils(String key
) {
42 } catch (InvalidKeyException e
) {
43 // We made sure that the key is correct, so nothing here
49 * Create a new instance of {@link CryptUtils} with the given 128 bytes key.
51 * The key <b>must</b> be exactly 128 bytes long.
54 * the 128 bits (32 bytes) of the key
56 * @throws InvalidKeyException
57 * if the key is not an array of 128 bytes
59 public CryptUtils(byte[] bytes32
) throws InvalidKeyException
{
64 * This method required an array of 128 bytes.
67 * the array, which <b>must</b> be of 128 bits (32 bytes)
69 * @throws InvalidKeyException
70 * if the key is not an array of 128 bits (32 bytes)
72 private void init(byte[] bytes32
) throws InvalidKeyException
{
73 if (bytes32
== null || bytes32
.length
!= 32) {
74 throw new InvalidKeyException(
75 "The size of the key must be of 128 bits (32 bytes), it is: "
76 + (bytes32
== null ?
"null" : "" + bytes32
.length
)
80 SecretKey key
= new SecretKeySpec(bytes32
, "AES");
82 ecipher
= Cipher
.getInstance("AES/ECB/PKCS5Padding");
83 dcipher
= Cipher
.getInstance("AES/ECB/PKCS5Padding");
84 ecipher
.init(Cipher
.ENCRYPT_MODE
, key
);
85 dcipher
.init(Cipher
.DECRYPT_MODE
, key
);
86 } catch (NoSuchAlgorithmException e
) {
87 // Every implementation of the Java platform is required to support
88 // this standard Cipher transformation with 128 bits keys
90 } catch (NoSuchPaddingException e
) {
91 // Every implementation of the Java platform is required to support
92 // this standard Cipher transformation with 128 bits keys
94 } catch (InvalidKeyException e
) {
95 // Every implementation of the Java platform is required to support
96 // this standard Cipher transformation with 128 bits keys
105 * the data to encrypt
107 * @return the encrypted data
109 * @throws SSLException
110 * in case of I/O error (i.e., the data is not what you assumed
113 public byte[] encrypt(byte[] data
) throws SSLException
{
115 return ecipher
.doFinal(data
);
116 } catch (IllegalBlockSizeException e
) {
117 throw new SSLException(e
);
118 } catch (BadPaddingException e
) {
119 throw new SSLException(e
);
127 * the data to encrypt
129 * @return the encrypted data
131 * @throws SSLException
132 * in case of I/O error (i.e., the data is not what you assumed
135 public byte[] encrypt(String data
) throws SSLException
{
137 return encrypt(data
.getBytes("UTF8"));
138 } catch (UnsupportedEncodingException e
) {
139 // UTF-8 is required in all confirm JVMs
146 * Encrypt the data, then encode it into Base64.
149 * the data to encrypt
151 * TRUE to also compress the data in GZIP format; remember that
152 * compressed and not-compressed content are different; you need
153 * to know which is which when decoding
155 * @return the encrypted data, encoded in Base64
157 * @throws SSLException
158 * in case of I/O error (i.e., the data is not what you assumed
161 public String
encrypt64(String data
, boolean zip
) throws SSLException
{
163 return encrypt64(data
.getBytes("UTF8"), zip
);
164 } catch (UnsupportedEncodingException e
) {
165 // UTF-8 is required in all confirm JVMs
172 * Encrypt the data, then encode it into Base64.
175 * the data to encrypt
177 * TRUE to also compress the data in GZIP format; remember that
178 * compressed and not-compressed content are different; you need
179 * to know which is which when decoding
181 * @return the encrypted data, encoded in Base64
183 * @throws SSLException
184 * in case of I/O error (i.e., the data is not what you assumed
187 public String
encrypt64(byte[] data
, boolean zip
) throws SSLException
{
189 return StringUtils
.base64(encrypt(data
), zip
);
190 } catch (IOException e
) {
191 // not exactly true, but we consider here that this error is a crypt
192 // error, not a normal I/O error
193 throw new SSLException(e
);
198 * Decode the data which is assumed to be encrypted with the same utilities.
201 * the encrypted data to decode
203 * @return the original, decoded data
205 * @throws SSLException
206 * in case of I/O error
208 public byte[] decrypt(byte[] data
) throws SSLException
{
210 return dcipher
.doFinal(data
);
211 } catch (IllegalBlockSizeException e
) {
212 throw new SSLException(e
);
213 } catch (BadPaddingException e
) {
214 throw new SSLException(e
);
219 * Decode the data which is assumed to be encrypted with the same utilities
220 * and is a Base64 encoded value.
223 * the encrypted data to decode in Base64 format
225 * TRUE to also uncompress the data from a GZIP format
226 * automatically; if set to FALSE, zipped data can be returned
228 * @return the original, decoded data
230 * @throws SSLException
231 * in case of I/O error
233 public byte[] decrypt64(String data
, boolean zip
) throws SSLException
{
235 return decrypt(StringUtils
.unbase64(data
, zip
));
236 } catch (IOException e
) {
237 // not exactly true, but we consider here that this error is a crypt
238 // error, not a normal I/O error
239 throw new SSLException(e
);
244 * Decode the data which is assumed to be encrypted with the same utilities
245 * and is a Base64 encoded value, then convert it into a String (this method
246 * assumes the data <b>was</b> indeed a UTF-8 encoded {@link String}).
249 * the encrypted data to decode in Base64 format
251 * TRUE to also uncompress the data from a GZIP format
252 * automatically; if set to FALSE, zipped data can be returned
254 * @return the original, decoded data
256 * @throws SSLException
257 * in case of I/O error
259 public String
decrypt64s(String data
, boolean zip
) throws SSLException
{
261 return new String(decrypt(StringUtils
.unbase64(data
, zip
)), "UTF-8");
262 } catch (UnsupportedEncodingException e
) {
263 // UTF-8 is required in all confirm JVMs
266 } catch (IOException e
) {
267 // not exactly true, but we consider here that this error is a crypt
268 // error, not a normal I/O error
269 throw new SSLException(e
);
274 * This is probably <b>NOT</b> secure!
277 * some {@link String} input
279 * @return a 128 bits key computed from the given input
281 static private byte[] key2key(String input
) {
282 return StringUtils
.getMd5Hash(input
).getBytes();