9
9
import java .nio .CharBuffer ;
10
10
import java .nio .charset .Charset ;
11
11
import java .security .GeneralSecurityException ;
12
- import java .security .Key ;
13
12
import java .security .NoSuchAlgorithmException ;
14
13
import java .security .Provider ;
15
14
import java .security .SecureRandom ;
@@ -129,17 +128,8 @@ public static SecretKey generateRandomSecretKey() throws NoSuchAlgorithmExceptio
129
128
130
129
/**
131
130
* Generate a SecretKey from a password using a PBE based algorithm
132
- *
133
- * Algorithms supported:
134
- *
135
- * PBEwithHmacSHA256AndAES_256
136
- * PBEWithHmacSHA1AndAES_256
137
- * PBEWithHmacSHA512AndAES_128
138
- * PBEWithHmacSHA1AndAES_128
139
- * PBEWithHmacSHA384AndAES_256
140
- * PBEWithMD5AndDES
141
- */
142
- public static SecretKey generateKeyFromPassword (String algorithm , char [] password ) throws GeneralSecurityException {
131
+ */
132
+ public static SecretKey generateKeyFromPassword (char [] password , String algorithm ) throws GeneralSecurityException {
143
133
// Convert the password bytes to Base64 characters because PBEKey class will not accept non-Ascii characters in a password
144
134
char [] encodedPassword = encodeCharsToBase64 (password );
145
135
@@ -150,17 +140,9 @@ public static SecretKey generateKeyFromPassword(String algorithm, char[] passwor
150
140
}
151
141
152
142
/**
153
- * Generate a SecretKey from a password using a PBK based algorithm with salt and iterations
154
- *
155
- * Algorithms supported:
156
- *
157
- * PBKDF2WithHmacSHA1
158
- * PBKDF2WithHmacSHA224
159
- * PBKDF2WithHmacSHA256
160
- * PBKDF2WithHmacSHA384
161
- * PBKDF2WithHmacSHA512
143
+ * Generate a SecretKey from a password using a PBK based algorithm
162
144
*/
163
- public static SecretKey generateKeyFromPassword (String algorithm , char [] password , byte [] salt , int iterations ) throws Exception {
145
+ public static SecretKey generateKeyFromPassword (char [] password , String algorithm , byte [] salt , int iterations ) throws GeneralSecurityException {
164
146
// Convert the password bytes to Base64 characters because PBEKey class will not accept non-Ascii characters in a password
165
147
char [] encodedPassword = encodeCharsToBase64 (password );
166
148
@@ -169,44 +151,94 @@ public static SecretKey generateKeyFromPassword(String algorithm, char[] passwor
169
151
SecretKeyFactory keyFactory = SecretKeyFactory .getInstance (algorithm );
170
152
SecretKey pbeKey = keyFactory .generateSecret (pbeKeySpec );
171
153
154
+ // Wrap the pbeKey in a SecretKeySpec
172
155
return new SecretKeySpec (pbeKey .getEncoded (), "AES" );
173
156
}
174
157
175
158
/**
176
- * Get and initialise Cipher based on PBE key from generateKeyFromPassword
159
+ * Encrypt/ Decrypt bytes with a password using a PBE based algorithm
177
160
*
178
- * @param key The secret PBE key generated from calling generateKeyFromPassword
179
- * @param algorithm The PBE transformation algorithm to use
161
+ * @param password Password
162
+ * @param pbeAlgorithm The PBE algorithm to use
180
163
* @param mode Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODE
181
- * @param salt Salt needed for PBEParameterSpec
182
- * @param iv Optional IV - some PBE algorithms don't use one
183
- * @param iterations
164
+ * @param bytes The bytes to encrypt/decypt
165
+ * @param salt Salt (required)
166
+ * @param iv IV (optional)
167
+ * @param iterations Iterations for the PBEParameterSpec
168
+ * @return The encrypted or decrypted bytes
184
169
*/
185
- public static Cipher getPBECipher (Key key , String algorithm , int mode , byte [] salt , byte [] iv , int iterations ) throws GeneralSecurityException {
186
- Cipher cipher = Cipher .getInstance (algorithm );
170
+ public static byte [] transformWithPassword (char [] password , String pbeAlgorithm , int mode , byte [] bytes , byte [] salt , byte [] iv ,
171
+ int iterations ) throws GeneralSecurityException {
172
+ // Generate a PBE key for the Cipher
173
+ SecretKey secretKey = generateKeyFromPassword (password , pbeAlgorithm );
174
+
175
+ // Encrypt the input with the Cipher
176
+ Cipher keyCipher = Cipher .getInstance (pbeAlgorithm );
187
177
188
- // PBEParameterSpec with salt and (optional) iv spec
178
+ // IvParameterSpec is optional depending on the algorithm
189
179
IvParameterSpec paramSpec = iv != null ? new IvParameterSpec (iv ) : null ;
190
180
191
- // Create parameters from the salt and an arbitrary number of iterations (paramSpec will be null if iv is null)
181
+ // Create parameters from the salt and the iterations (paramSpec will be null if iv is null)
192
182
PBEParameterSpec pbeParamSpec = new PBEParameterSpec (salt , iterations , paramSpec );
193
-
183
+
194
184
// Set the cipher mode to decryption or encryption
195
- cipher .init (mode , key , pbeParamSpec );
185
+ keyCipher .init (mode , secretKey , pbeParamSpec );
186
+
187
+ // Encypt/Decrypt the bytes
188
+ return keyCipher .doFinal (bytes );
189
+ }
196
190
197
- return cipher ;
191
+ /**
192
+ * Encrypt/ Decrypt bytes with a password using a PBK based algorithm
193
+ *
194
+ * @param password Password
195
+ * @param pbkAlgorithm The PBK algorithm to use
196
+ * @param cipherAlgorithm The Cipher algorithm to use - AES or AES/CBC/PKCS5Padding or AES/GCM/NoPadding
197
+ * @param mode Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODE
198
+ * @param bytes The bytes to encrypt/decypt
199
+ * @param salt Salt (required)
200
+ * @param iv IV (required)
201
+ * @param iterations Iterations for the PBEKeySpec
202
+ * @return The encrypted or decrypted bytes
203
+ */
204
+ public static byte [] transformWithPassword2 (char [] password , String pbkAlgorithm , String cipherAlgorithm , int mode , byte [] bytes , byte [] salt , byte [] iv ,
205
+ int iterations ) throws GeneralSecurityException {
206
+ // Generate a key with the PBK Algorithm
207
+ SecretKey secretKey = generateKeyFromPassword (password , pbkAlgorithm , salt , iterations );
208
+
209
+ // Get the cipher from the key and cipher algorithm
210
+ Cipher keyCipher = getCipher (secretKey , cipherAlgorithm , mode , iv );
211
+
212
+ // Encypt/Decrypt the bytes
213
+ return keyCipher .doFinal (bytes );
214
+ }
215
+
216
+ /**
217
+ * Encrypt/ Decrypt bytes with a SecretKey
218
+ *
219
+ * @param key The secret key to use for the Cipher
220
+ * @param cipherAlgorithm The Cipher algorithm to use - AES or AES/CBC/PKCS5Padding or AES/GCM/NoPadding
221
+ * @param mode Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODE
222
+ * @param bytes The bytes to encrypt/decypt
223
+ * @param iv IV (optional)
224
+ * @return The encrypted or decrypted bytes
225
+ * @throws GeneralSecurityException
226
+ */
227
+ public static byte [] transformWithKey (SecretKey key , String cipherAlgorithm , int mode , byte [] bytes , byte [] iv ) throws GeneralSecurityException {
228
+ Cipher cipher = getCipher (key , cipherAlgorithm , mode , iv );
229
+ return cipher .doFinal (bytes );
198
230
}
199
231
200
232
/**
201
233
* Get and initialise Cipher with a secret key and optional iv
202
- * param @iv is optional and not used for AES
234
+ * param @iv is optional and not used for AES, AES/CBC/PKCS5Padding or AES/GCM/NoPadding
203
235
*
204
- * @param key The scret key
205
- * @param algorithm The transformation algorithm to use
236
+ * @param key The secret key
237
+ * @param algorithm The transformation algorithm to use - AES,
206
238
* @param mode Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODE
207
239
* @param iv Optional IV
208
240
*/
209
- public static Cipher getCipher (Key key , String algorithm , int mode , byte ... iv ) throws GeneralSecurityException {
241
+ public static Cipher getCipher (SecretKey key , String algorithm , int mode , byte ... iv ) throws GeneralSecurityException {
210
242
Cipher cipher = Cipher .getInstance (algorithm );
211
243
212
244
switch (algorithm ) {
0 commit comments