Path: blob/master/test/jdk/com/sun/crypto/provider/Cipher/TextLength/PBECipherWrapper.java
41161 views
/*1* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.security.AlgorithmParameters;24import java.security.InvalidAlgorithmParameterException;25import java.security.InvalidKeyException;26import java.security.NoSuchAlgorithmException;27import java.security.spec.AlgorithmParameterSpec;28import java.security.spec.InvalidKeySpecException;29import java.security.spec.InvalidParameterSpecException;30import java.util.Arrays;31import java.util.List;32import java.util.ArrayList;33import javax.crypto.BadPaddingException;34import javax.crypto.Cipher;35import javax.crypto.IllegalBlockSizeException;36import javax.crypto.NoSuchPaddingException;37import javax.crypto.SecretKey;38import javax.crypto.SecretKeyFactory;39import javax.crypto.ShortBufferException;40import javax.crypto.spec.IvParameterSpec;41import javax.crypto.spec.PBEKeySpec;42import javax.crypto.spec.PBEParameterSpec;43import javax.crypto.spec.SecretKeySpec;4445/**46* PBECipherWrapper is the abstract class for all concrete PBE Cipher wrappers.47*/48public abstract class PBECipherWrapper {4950public static final int ITERATION_COUNT = 1000;51private final String algorithm;52private final byte[] salt;53protected SecretKey key;54protected Cipher ci;55protected String baseAlgo;56protected byte[] resultText = null;57protected AlgorithmParameterSpec aps = null;5859public PBECipherWrapper(String algorithm, int saltSize) {60this.algorithm = algorithm;61baseAlgo = algorithm.split("/")[0].toUpperCase();62salt = generateSalt(saltSize);63}6465protected abstract void initCipher(int mode) throws InvalidKeyException,66InvalidAlgorithmParameterException, InvalidParameterSpecException;6768public void execute(int edMode, byte[] inputText)69throws InvalidAlgorithmParameterException,70InvalidParameterSpecException, IllegalBlockSizeException,71BadPaddingException, ShortBufferException, InvalidKeyException {72// Initialize73initCipher(edMode);7475// Generate a resultText using a single-part enc/dec76resultText = ci.doFinal(inputText);7778// Generate outputText for each multi-part en/de-cryption79/* Combination #1:80update(byte[], int, int)81doFinal(byte[], int, int)82*/83byte[] part11 = ci.update(inputText, 0, inputText.length);84byte[] part12 = ci.doFinal();85byte[] outputText1 = new byte[part11.length + part12.length];86System.arraycopy(part11, 0, outputText1, 0, part11.length);87System.arraycopy(part12, 0, outputText1, part11.length, part12.length);8889List<byte[]> outputTexts = new ArrayList<>(4);90outputTexts.add(outputText1);9192/* Combination #2:93update(byte[], int, int)94doFinal(byte[], int, int, byte[], int)95*/96byte[] part21 = ci.update(inputText, 0, inputText.length - 5);97byte[] part22 = new byte[ci.getOutputSize(inputText.length)];98int len2 = ci.doFinal(inputText, inputText.length - 5, 5, part22, 0);99byte[] outputText2 = new byte[part21.length + len2];100System.arraycopy(part21, 0, outputText2, 0, part21.length);101System.arraycopy(part22, 0, outputText2, part21.length, len2);102103outputTexts.add(outputText2);104105/* Combination #3:106update(byte[], int, int, byte[], int)107doFinal(byte[], int, int)108*/109byte[] part31 = new byte[ci.getOutputSize(inputText.length)];110int len3 = ci.update(inputText, 0, inputText.length - 8, part31, 0);111byte[] part32 = ci.doFinal(inputText, inputText.length - 8, 8);112byte[] outputText3 = new byte[len3 + part32.length];113System.arraycopy(part31, 0, outputText3, 0, len3);114System.arraycopy(part32, 0, outputText3, len3, part32.length);115116outputTexts.add(outputText3);117118/* Combination #4:119update(byte[], int, int, byte[], int)120doFinal(byte[], int, int, byte[], int)121*/122byte[] part41 = new byte[ci.getOutputSize(inputText.length)];123int len4 = ci.update(inputText, 0, inputText.length - 8, part41, 0);124int rest4 = ci125.doFinal(inputText, inputText.length - 8, 8, part41, len4);126byte[] outputText4 = new byte[len4 + rest4];127System.arraycopy(part41, 0, outputText4, 0, outputText4.length);128129outputTexts.add(outputText4);130131// Compare results132for (int k = 0; k < outputTexts.size(); k++) {133if (!Arrays.equals(resultText, outputTexts.get(k))) {134throw new RuntimeException(135"Compare value of resultText and combination " + k136+ " are not same. Test failed.");137}138}139140}141142public final byte[] generateSalt(int numberOfBytes) {143byte[] aSalt = new byte[numberOfBytes];144for (int i = 0; i < numberOfBytes; i++) {145aSalt[i] = (byte) (i & 0xff);146}147return aSalt;148}149150public byte[] getResult() {151return resultText;152}153154public String getAlgorithm() {155return algorithm;156}157158public byte[] getSalt() {159return salt;160}161162/**163* Wrapper class to test a given SecretKeyFactory.PBKDF2 algorithm.164*/165public static class PBKDF2 extends PBECipherWrapper {166167private static final int PBKDF2_SALT_SIZE = 64;168private static final int CIPHER_KEY_SIZE = 128;169private static final String CIPHER_TRANSFORMATION = "AES/CBC/PKCS5Padding";170private static final String KEY_ALGORITHM = "AES";171private byte[] iv = null;172173public PBKDF2(String algo, String passwd)174throws InvalidKeySpecException, NoSuchAlgorithmException,175NoSuchPaddingException {176super(algo, PBKDF2_SALT_SIZE);177178ci = Cipher.getInstance(CIPHER_TRANSFORMATION);179180PBEKeySpec pbeKeySpec = new PBEKeySpec(passwd.toCharArray(), getSalt(),181ITERATION_COUNT, CIPHER_KEY_SIZE);182SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algo);183key = keyFactory.generateSecret(pbeKeySpec);184}185186@Override187protected void initCipher(int mode) throws InvalidKeyException,188InvalidAlgorithmParameterException, InvalidParameterSpecException {189if (Cipher.ENCRYPT_MODE == mode) {190ci.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getEncoded(),191KEY_ALGORITHM));192iv = ci.getParameters().getParameterSpec(IvParameterSpec.class)193.getIV();194} else {195ci.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getEncoded(),196KEY_ALGORITHM), new IvParameterSpec(iv));197}198}199}200201/**202* Wrapper class to test a given AES-based PBE algorithm.203*/204public static class AES extends PBECipherWrapper {205206private AlgorithmParameters pbeParams;207208public AES(String algo, String passwd)209throws NoSuchAlgorithmException, NoSuchPaddingException,210InvalidKeySpecException {211super(algo, 0);212213ci = Cipher.getInstance(algo);214215SecretKeyFactory skf = SecretKeyFactory.getInstance(algo);216key = skf.generateSecret(new PBEKeySpec(passwd.toCharArray()));217}218219@Override220protected void initCipher(int mode) throws InvalidKeyException,221InvalidAlgorithmParameterException, InvalidParameterSpecException {222if (Cipher.ENCRYPT_MODE == mode) {223ci.init(Cipher.ENCRYPT_MODE, key);224pbeParams = ci.getParameters();225} else {226ci.init(Cipher.DECRYPT_MODE, key, pbeParams);227}228}229}230231/**232* Wrapper class to test a given PBE algorithm.233*/234public static class Legacy extends PBECipherWrapper {235236private static final int PBE_SALT_SIZE = 8;237238public Legacy(String algo, String passwd)239throws NoSuchAlgorithmException, NoSuchPaddingException,240InvalidKeySpecException {241super(algo, PBE_SALT_SIZE);242243SecretKeyFactory skf = SecretKeyFactory.getInstance(algo.split("/")[0]);244key = skf.generateSecret(new PBEKeySpec(passwd.toCharArray()));245246aps = new PBEParameterSpec(getSalt(), ITERATION_COUNT);247248ci = Cipher.getInstance(algo);249}250251@Override252protected void initCipher(int mode) throws InvalidKeyException,253InvalidAlgorithmParameterException, InvalidParameterSpecException {254ci.init(mode, key, aps);255}256}257}258259260