1 package org
.argeo
.util
.crypto
;
3 import java
.io
.ByteArrayInputStream
;
4 import java
.io
.ByteArrayOutputStream
;
5 import java
.io
.IOException
;
6 import java
.io
.InputStream
;
7 import java
.io
.OutputStream
;
8 import java
.security
.Key
;
10 import javax
.crypto
.Cipher
;
11 import javax
.crypto
.CipherInputStream
;
12 import javax
.crypto
.CipherOutputStream
;
13 import javax
.crypto
.SecretKey
;
14 import javax
.crypto
.SecretKeyFactory
;
15 import javax
.crypto
.spec
.IvParameterSpec
;
16 import javax
.crypto
.spec
.PBEKeySpec
;
17 import javax
.crypto
.spec
.SecretKeySpec
;
19 import org
.argeo
.ArgeoException
;
20 import org
.argeo
.StreamUtils
;
22 /** Simple password based encryption / decryption */
23 public class PasswordBasedEncryption
{
24 public final static Integer DEFAULT_ITERATION_COUNT
= 1024;
25 public final static Integer DEFAULT_KEY_LENGTH
= 256;
26 public final static String DEFAULT_SECRETE_KEY_FACTORY
= "PBKDF2WithHmacSHA1";
27 public final static String DEFAULT_SECRETE_KEY_ENCRYPTION
= "AES";
28 public final static String DEFAULT_CIPHER
= "AES/CBC/PKCS5Padding";
29 public final static String DEFAULT_CHARSET
= "UTF-8";
31 private static byte[] DEFAULT_SALT_8
= { (byte) 0xA9, (byte) 0x9B,
32 (byte) 0xC8, (byte) 0x32, (byte) 0x56, (byte) 0x35, (byte) 0xE3,
34 private static byte[] DEFAULT_IV_16
= { (byte) 0xA9, (byte) 0x9B,
35 (byte) 0xC8, (byte) 0x32, (byte) 0x56, (byte) 0x35, (byte) 0xE3,
36 (byte) 0x03, (byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32,
37 (byte) 0x56, (byte) 0x35, (byte) 0xE3, (byte) 0x03 };
39 private final Key key
;
40 private final Cipher ecipher
;
41 private final Cipher dcipher
;
43 public PasswordBasedEncryption(char[] password
) {
44 this(password
, DEFAULT_SALT_8
, DEFAULT_IV_16
);
47 public PasswordBasedEncryption(char[] password
, byte[] passwordSalt
,
48 byte[] initializationVector
) {
50 byte[] salt
= new byte[8];
51 System
.arraycopy(passwordSalt
, 0, salt
, 0, salt
.length
);
52 // for (int i = 0; i < password.length && i < salt.length; i++)
53 // salt[i] = (byte) password[i];
54 byte[] iv
= new byte[16];
55 System
.arraycopy(initializationVector
, 0, iv
, 0, iv
.length
);
56 // for (int i = 0; i < password.length && i < iv.length; i++)
57 // iv[i] = (byte) password[i];
59 SecretKeyFactory keyFac
= SecretKeyFactory
60 .getInstance(getSecretKeyFactoryName());
61 PBEKeySpec keySpec
= new PBEKeySpec(password
, salt
,
62 getIterationCount(), getKeyLength());
63 String secKeyEncryption
= getSecretKeyEncryption();
64 if (secKeyEncryption
!= null) {
65 SecretKey tmp
= keyFac
.generateSecret(keySpec
);
66 key
= new SecretKeySpec(tmp
.getEncoded(),
67 getSecretKeyEncryption());
69 key
= keyFac
.generateSecret(keySpec
);
71 ecipher
= Cipher
.getInstance(getCipherName());
72 ecipher
.init(Cipher
.ENCRYPT_MODE
, key
, new IvParameterSpec(iv
));
73 // AlgorithmParameters params = ecipher.getParameters();
75 // params.getParameterSpec(IvParameterSpec.class).getIV();
76 dcipher
= Cipher
.getInstance(getCipherName());
77 dcipher
.init(Cipher
.DECRYPT_MODE
, key
, new IvParameterSpec(iv
));
78 } catch (Exception e
) {
79 throw new ArgeoException("Cannot get secret key", e
);
83 public void encrypt(InputStream decryptedIn
, OutputStream encryptedOut
)
86 CipherOutputStream out
= new CipherOutputStream(encryptedOut
,
88 StreamUtils
.copy(decryptedIn
, out
);
89 StreamUtils
.closeQuietly(out
);
90 } catch (IOException e
) {
92 } catch (Exception e
) {
93 throw new ArgeoException("Cannot encrypt", e
);
95 StreamUtils
.closeQuietly(decryptedIn
);
99 public void decrypt(InputStream encryptedIn
, OutputStream decryptedOut
)
102 CipherInputStream decryptedIn
= new CipherInputStream(encryptedIn
,
104 StreamUtils
.copy(decryptedIn
, decryptedOut
);
105 } catch (IOException e
) {
107 } catch (Exception e
) {
108 throw new ArgeoException("Cannot decrypt", e
);
110 StreamUtils
.closeQuietly(encryptedIn
);
114 public byte[] encryptString(String str
) {
115 ByteArrayOutputStream out
= null;
116 ByteArrayInputStream in
= null;
118 out
= new ByteArrayOutputStream();
119 in
= new ByteArrayInputStream(str
.getBytes(DEFAULT_CHARSET
));
121 return out
.toByteArray();
122 } catch (Exception e
) {
123 throw new ArgeoException("Cannot encrypt", e
);
125 StreamUtils
.closeQuietly(out
);
129 /** Closes the input stream */
130 public String
decryptAsString(InputStream in
) {
131 ByteArrayOutputStream out
= null;
133 out
= new ByteArrayOutputStream();
135 return new String(out
.toByteArray(), DEFAULT_CHARSET
);
136 } catch (Exception e
) {
137 throw new ArgeoException("Cannot decrypt", e
);
139 StreamUtils
.closeQuietly(out
);
143 protected Key
getKey() {
147 protected Cipher
getEcipher() {
151 protected Cipher
getDcipher() {
155 protected Integer
getIterationCount() {
156 return DEFAULT_ITERATION_COUNT
;
159 protected Integer
getKeyLength() {
160 return DEFAULT_KEY_LENGTH
;
163 protected String
getSecretKeyFactoryName() {
164 return DEFAULT_SECRETE_KEY_FACTORY
;
167 protected String
getSecretKeyEncryption() {
168 return DEFAULT_SECRETE_KEY_ENCRYPTION
;
171 protected String
getCipherName() {
172 return DEFAULT_CIPHER
;