1 /*
2 * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
243
244 byte[] derivedKey = deriveCipherKey(key);
245 // use all but the last 8 bytes as the key value
246 SecretKeySpec cipherKey = new SecretKeySpec(derivedKey, 0,
247 derivedKey.length-8, algo);
248 // use the last 8 bytes as the IV
249 IvParameterSpec ivSpec = new IvParameterSpec(derivedKey,
250 derivedKey.length-8,
251 8);
252 // initialize the underlying cipher
253 cipher.init(opmode, cipherKey, ivSpec, random);
254 }
255
256 private byte[] deriveCipherKey(Key key) {
257
258 byte[] result = null;
259 byte[] passwdBytes = key.getEncoded();
260
261 if (algo.equals("DES")) {
262 // P || S (password concatenated with salt)
263 byte[] concat = new byte[passwdBytes.length + salt.length];
264 System.arraycopy(passwdBytes, 0, concat, 0, passwdBytes.length);
265 java.util.Arrays.fill(passwdBytes, (byte)0x00);
266 System.arraycopy(salt, 0, concat, passwdBytes.length, salt.length);
267
268 // digest P || S with c iterations
269 byte[] toBeHashed = concat;
270 for (int i = 0; i < iCount; i++) {
271 md.update(toBeHashed);
272 toBeHashed = md.digest(); // this resets the digest
273 }
274 java.util.Arrays.fill(concat, (byte)0x00);
275 result = toBeHashed;
276 } else if (algo.equals("DESede")) {
277 // if the 2 salt halves are the same, invert one of them
278 int i;
279 for (i=0; i<4; i++) {
280 if (salt[i] != salt[i+4])
281 break;
282 }
283 if (i==4) { // same, invert 1st half
284 for (i=0; i<2; i++) {
285 byte tmp = salt[i];
286 salt[i] = salt[3-i];
287 salt[3-1] = tmp;
288 }
289 }
290
291 // Now digest each half (concatenated with password). For each
292 // half, go through the loop as many times as specified by the
293 // iteration count parameter (inner for loop).
294 // Concatenate the output from each digest round with the
295 // password, and use the result as the input to the next digest
296 // operation.
297 byte[] kBytes = null;
298 IvParameterSpec iv = null;
299 byte[] toBeHashed = null;
300 result = new byte[DESedeKeySpec.DES_EDE_KEY_LEN +
301 DESConstants.DES_BLOCK_SIZE];
302 for (i = 0; i < 2; i++) {
303 toBeHashed = new byte[salt.length/2];
304 System.arraycopy(salt, i*(salt.length/2), toBeHashed, 0,
305 toBeHashed.length);
306 for (int j=0; j < iCount; j++) {
307 md.update(toBeHashed);
|
1 /*
2 * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
243
244 byte[] derivedKey = deriveCipherKey(key);
245 // use all but the last 8 bytes as the key value
246 SecretKeySpec cipherKey = new SecretKeySpec(derivedKey, 0,
247 derivedKey.length-8, algo);
248 // use the last 8 bytes as the IV
249 IvParameterSpec ivSpec = new IvParameterSpec(derivedKey,
250 derivedKey.length-8,
251 8);
252 // initialize the underlying cipher
253 cipher.init(opmode, cipherKey, ivSpec, random);
254 }
255
256 private byte[] deriveCipherKey(Key key) {
257
258 byte[] result = null;
259 byte[] passwdBytes = key.getEncoded();
260
261 if (algo.equals("DES")) {
262 // P || S (password concatenated with salt)
263 byte[] concat = new byte[Math.addExact(passwdBytes.length, salt.length)];
264 System.arraycopy(passwdBytes, 0, concat, 0, passwdBytes.length);
265 java.util.Arrays.fill(passwdBytes, (byte)0x00);
266 System.arraycopy(salt, 0, concat, passwdBytes.length, salt.length);
267
268 // digest P || S with c iterations
269 byte[] toBeHashed = concat;
270 for (int i = 0; i < iCount; i++) {
271 md.update(toBeHashed);
272 toBeHashed = md.digest(); // this resets the digest
273 }
274 java.util.Arrays.fill(concat, (byte)0x00);
275 result = toBeHashed;
276 } else if (algo.equals("DESede")) {
277 // if the 2 salt halves are the same, invert one of them
278 int i;
279 for (i=0; i<4; i++) {
280 if (salt[i] != salt[i+4])
281 break;
282 }
283 if (i==4) { // same, invert 1st half
284 for (i=0; i<2; i++) {
285 byte tmp = salt[i];
286 salt[i] = salt[3-i];
287 salt[3-i] = tmp;
288 }
289 }
290
291 // Now digest each half (concatenated with password). For each
292 // half, go through the loop as many times as specified by the
293 // iteration count parameter (inner for loop).
294 // Concatenate the output from each digest round with the
295 // password, and use the result as the input to the next digest
296 // operation.
297 byte[] kBytes = null;
298 IvParameterSpec iv = null;
299 byte[] toBeHashed = null;
300 result = new byte[DESedeKeySpec.DES_EDE_KEY_LEN +
301 DESConstants.DES_BLOCK_SIZE];
302 for (i = 0; i < 2; i++) {
303 toBeHashed = new byte[salt.length/2];
304 System.arraycopy(salt, i*(salt.length/2), toBeHashed, 0,
305 toBeHashed.length);
306 for (int j=0; j < iCount; j++) {
307 md.update(toBeHashed);
|