| /* |
| * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| import static java.lang.System.out; |
| |
| import java.security.InvalidAlgorithmParameterException; |
| import java.security.InvalidKeyException; |
| import java.security.NoSuchAlgorithmException; |
| import java.security.spec.AlgorithmParameterSpec; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| import javax.crypto.BadPaddingException; |
| import javax.crypto.IllegalBlockSizeException; |
| import javax.crypto.SecretKey; |
| import javax.crypto.ShortBufferException; |
| import javax.crypto.Cipher; |
| import javax.crypto.KeyGenerator; |
| import javax.crypto.NoSuchPaddingException; |
| import javax.crypto.spec.IvParameterSpec; |
| |
| /** |
| * Wrapper class to test a given DES algorithm. |
| */ |
| public class DESCipherWrapper { |
| |
| private final Cipher ci; |
| private final byte[] iv; |
| private final SecretKey key; |
| private final String algo; |
| private final String mode; |
| private final String pad; |
| private final int keyStrength; |
| private byte[] resultText = null; |
| |
| public DESCipherWrapper(String algo, String mode, String pad) |
| throws NoSuchAlgorithmException, NoSuchPaddingException { |
| ci = Cipher.getInstance(algo + "/" + mode + "/" + pad); |
| |
| iv = new byte[8]; |
| for (int i = 0; i < 8; i++) { |
| iv[i] = (byte) (i & 0xff); |
| } |
| |
| KeyGenerator kg = KeyGenerator.getInstance(algo); |
| key = kg.generateKey(); |
| keyStrength = algo.equalsIgnoreCase("DESede") ? 112 |
| : key.getEncoded().length * 8; |
| |
| this.algo = algo; |
| this.mode = mode; |
| this.pad = pad; |
| } |
| |
| public byte[] getResult() { |
| return resultText.clone(); |
| } |
| |
| public void execute(int edMode, byte[] inputText) |
| throws InvalidKeyException, InvalidAlgorithmParameterException, |
| IllegalBlockSizeException, BadPaddingException, |
| ShortBufferException, NoSuchAlgorithmException { |
| AlgorithmParameterSpec aps = null; |
| |
| try { |
| if (!mode.equalsIgnoreCase("ECB")) { |
| aps = new IvParameterSpec(iv); |
| } |
| ci.init(edMode, key, aps); |
| |
| // Generate a resultText using a single-part enc/dec |
| resultText = ci.doFinal(inputText); |
| |
| // Generate outputText for each multi-part en/de-cryption |
| /* Combination #1: |
| update(byte[], int, int) |
| doFinal(byte[], int, int) |
| */ |
| byte[] part11 = ci.update(inputText, 0, inputText.length); |
| byte[] part12 = ci.doFinal(); |
| byte[] outputText1 = new byte[part11.length + part12.length]; |
| System.arraycopy(part11, 0, outputText1, 0, part11.length); |
| System.arraycopy(part12, 0, outputText1, part11.length, |
| part12.length); |
| |
| List<byte[]> outputTexts = new ArrayList<>(4); |
| outputTexts.add(outputText1); |
| |
| /* Combination #2: |
| update(byte[], int, int) |
| doFinal(byte[], int, int, byte[], int) |
| */ |
| byte[] part21 = ci.update(inputText, 0, inputText.length - 5); |
| byte[] part22 = new byte[ci.getOutputSize(inputText.length)]; |
| int len2 = ci |
| .doFinal(inputText, inputText.length - 5, 5, part22, 0); |
| byte[] outputText2 = new byte[part21.length + len2]; |
| System.arraycopy(part21, 0, outputText2, 0, part21.length); |
| System.arraycopy(part22, 0, outputText2, part21.length, len2); |
| |
| outputTexts.add(outputText2); |
| |
| /* Combination #3: |
| update(byte[], int, int, byte[], int) |
| doFinal(byte[], int, int) |
| */ |
| byte[] part31 = new byte[ci.getOutputSize(inputText.length)]; |
| int len3 = ci.update(inputText, 0, inputText.length - 8, part31, 0); |
| byte[] part32 = ci.doFinal(inputText, inputText.length - 8, 8); |
| byte[] outputText3 = new byte[len3 + part32.length]; |
| System.arraycopy(part31, 0, outputText3, 0, len3); |
| System.arraycopy(part32, 0, outputText3, len3, part32.length); |
| |
| outputTexts.add(outputText3); |
| |
| /* Combination #4: |
| update(byte[], int, int, byte[], int) |
| doFinal(byte[], int, int, byte[], int) |
| */ |
| byte[] part41 = new byte[ci.getOutputSize(inputText.length)]; |
| int len4 = ci.update(inputText, 0, inputText.length - 8, part41, 0); |
| int rest4 = ci.doFinal(inputText, inputText.length - 8, 8, part41, |
| len4); |
| byte[] outputText4 = new byte[len4 + rest4]; |
| System.arraycopy(part41, 0, outputText4, 0, outputText4.length); |
| |
| outputTexts.add(outputText4); |
| |
| // Compare results |
| for (int k = 0; k < outputTexts.size(); k++) { |
| if (!Arrays.equals(resultText, outputTexts.get(k))) { |
| out.println(" Testing: " + algo + "/" + mode + "/" + pad); |
| throw new RuntimeException( |
| "Compare value of resultText and combination " + k |
| + " are not same. Test failed."); |
| } |
| } |
| if (keyStrength > Cipher.getMaxAllowedKeyLength(algo)) { |
| throw new RuntimeException( |
| "Expected exception uncaught, keyStrength " |
| + keyStrength); |
| } |
| } catch (InvalidKeyException ex) { |
| if (keyStrength <= Cipher.getMaxAllowedKeyLength(algo)) { |
| out.println("Unexpected exception in " + algo + "/" + mode |
| + "/" + pad + " , KeySize " + keyStrength); |
| throw ex; |
| } |
| out.println("Caught InvalidKeyException as expected"); |
| } |
| } |
| } |