]> git.argeo.org Git - lgpl/argeo-commons.git/blob - PasswordBasedEncryption.java
ab36e5d8f00e02937a6cd0d396037bf846798f88
[lgpl/argeo-commons.git] / PasswordBasedEncryption.java
1 package org.argeo.util.crypto;
2
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;
9
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;
18
19 import org.argeo.ArgeoException;
20 import org.argeo.StreamUtils;
21
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";
30
31 private static byte[] DEFAULT_SALT_8 = { (byte) 0xA9, (byte) 0x9B,
32 (byte) 0xC8, (byte) 0x32, (byte) 0x56, (byte) 0x35, (byte) 0xE3,
33 (byte) 0x03 };
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 };
38
39 private final Key key;
40 private final Cipher ecipher;
41 private final Cipher dcipher;
42
43 public PasswordBasedEncryption(char[] password) {
44 this(password, DEFAULT_SALT_8, DEFAULT_IV_16);
45 }
46
47 public PasswordBasedEncryption(char[] password, byte[] passwordSalt,
48 byte[] initializationVector) {
49 try {
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];
58
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());
68 } else {
69 key = keyFac.generateSecret(keySpec);
70 }
71 ecipher = Cipher.getInstance(getCipherName());
72 ecipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
73 // AlgorithmParameters params = ecipher.getParameters();
74 // byte[] iv =
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);
80 }
81 }
82
83 public void encrypt(InputStream decryptedIn, OutputStream encryptedOut)
84 throws IOException {
85 try {
86 CipherOutputStream out = new CipherOutputStream(encryptedOut,
87 ecipher);
88 StreamUtils.copy(decryptedIn, out);
89 StreamUtils.closeQuietly(out);
90 } catch (IOException e) {
91 throw e;
92 } catch (Exception e) {
93 throw new ArgeoException("Cannot encrypt", e);
94 } finally {
95 StreamUtils.closeQuietly(decryptedIn);
96 }
97 }
98
99 public void decrypt(InputStream encryptedIn, OutputStream decryptedOut)
100 throws IOException {
101 try {
102 CipherInputStream decryptedIn = new CipherInputStream(encryptedIn,
103 dcipher);
104 StreamUtils.copy(decryptedIn, decryptedOut);
105 } catch (IOException e) {
106 throw e;
107 } catch (Exception e) {
108 throw new ArgeoException("Cannot decrypt", e);
109 } finally {
110 StreamUtils.closeQuietly(encryptedIn);
111 }
112 }
113
114 public byte[] encryptString(String str) {
115 ByteArrayOutputStream out = null;
116 ByteArrayInputStream in = null;
117 try {
118 out = new ByteArrayOutputStream();
119 in = new ByteArrayInputStream(str.getBytes(DEFAULT_CHARSET));
120 encrypt(in, out);
121 return out.toByteArray();
122 } catch (Exception e) {
123 throw new ArgeoException("Cannot encrypt", e);
124 } finally {
125 StreamUtils.closeQuietly(out);
126 }
127 }
128
129 /** Closes the input stream */
130 public String decryptAsString(InputStream in) {
131 ByteArrayOutputStream out = null;
132 try {
133 out = new ByteArrayOutputStream();
134 decrypt(in, out);
135 return new String(out.toByteArray(), DEFAULT_CHARSET);
136 } catch (Exception e) {
137 throw new ArgeoException("Cannot decrypt", e);
138 } finally {
139 StreamUtils.closeQuietly(out);
140 }
141 }
142
143 protected Key getKey() {
144 return key;
145 }
146
147 protected Cipher getEcipher() {
148 return ecipher;
149 }
150
151 protected Cipher getDcipher() {
152 return dcipher;
153 }
154
155 protected Integer getIterationCount() {
156 return DEFAULT_ITERATION_COUNT;
157 }
158
159 protected Integer getKeyLength() {
160 return DEFAULT_KEY_LENGTH;
161 }
162
163 protected String getSecretKeyFactoryName() {
164 return DEFAULT_SECRETE_KEY_FACTORY;
165 }
166
167 protected String getSecretKeyEncryption() {
168 return DEFAULT_SECRETE_KEY_ENCRYPTION;
169 }
170
171 protected String getCipherName() {
172 return DEFAULT_CIPHER;
173 }
174 }