Path: blob/master/test/jdk/com/sun/crypto/provider/Cipher/PBE/PBKDF2Translate.java
41161 views
/*1* Copyright (c) 2012, 2014, 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.InvalidKeyException;24import java.security.NoSuchAlgorithmException;25import java.security.spec.InvalidKeySpecException;26import java.util.Arrays;27import java.util.Random;28import javax.crypto.SecretKey;29import javax.crypto.SecretKeyFactory;30import javax.crypto.interfaces.PBEKey;31import javax.crypto.spec.PBEKeySpec;3233/**34* @test35* @bug 804178136* @summary Verify if the SecretKeyFactory.translateKey() method works37* @author Alexander Fomin38* @run main PBKDF2Translate39* @key randomness40*/41public class PBKDF2Translate {4243private static final String[] ALGO_TO_TEST = {44"PBKDF2WithHmacSHA1",45"PBKDF2WithHmacSHA224",46"PBKDF2WithHmacSHA256",47"PBKDF2WithHmacSHA384",48"PBKDF2WithHmacSHA512"49};5051private static final String PASS_PHRASE = "some hidden string";52private static final int ITERATION_COUNT = 1000;53private static final int KEY_SIZE = 128;5455private final String algoToTest;56private final byte[] salt = new byte[8];5758public static void main(String[] args) throws Exception {5960boolean failed = false;6162for (String algo : ALGO_TO_TEST) {6364System.out.println("Testing " + algo + ":");65PBKDF2Translate theTest = new PBKDF2Translate(algo);6667try {68if (!theTest.testMyOwnSecretKey()69|| !theTest.generateAndTranslateKey()70|| !theTest.translateSpoiledKey()) {71// we don't want to set failed to false72failed = true;73}74} catch (InvalidKeyException | NoSuchAlgorithmException |75InvalidKeySpecException e) {76e.printStackTrace(System.err);77failed = true;78}79}8081if (failed) {82throw new RuntimeException("One or more tests failed....");83}84}8586public PBKDF2Translate(String algoToTest) {87this.algoToTest = algoToTest;88new Random().nextBytes(this.salt);89}9091/**92* The test case scenario implemented in the method: - derive PBKDF2 key93* using the given algorithm; - translate the key - check if the translated94* and original keys have the same key value.95*96* @return true if the test case passed; false - otherwise.97* @throws NoSuchAlgorithmException98* @throws InvalidKeySpecException99* @throws InvalidKeyException100*/101public boolean generateAndTranslateKey() throws NoSuchAlgorithmException,102InvalidKeySpecException, InvalidKeyException {103// derive PBKDF2 key104SecretKey key1 = getSecretKeyForPBKDF2(algoToTest);105106// translate key107SecretKeyFactory skf = SecretKeyFactory.getInstance(algoToTest);108SecretKey key2 = skf.translateKey(key1);109110// check if it still the same after translation111if (!Arrays.equals(key1.getEncoded(), key2.getEncoded())) {112System.err.println("generateAndTranslateKey test case failed: the "113+ "key1 and key2 values in its primary encoding format are "114+ "not the same for " + algoToTest + "algorithm.");115return false;116}117118return true;119}120121/**122* The test case scenario implemented in the method: - derive Key1 for the123* given PBKDF2 algorithm - create my own secret Key2 as an instance of a124* class implements PBEKey - translate Key2 - check if the key value of the125* translated key and Key1 are the same.126*127* @return true if the test case passed; false - otherwise.128* @throws NoSuchAlgorithmException129* @throws InvalidKeySpecException130* @throws InvalidKeyException131*/132public boolean testMyOwnSecretKey()133throws NoSuchAlgorithmException, InvalidKeySpecException,134InvalidKeyException {135SecretKey key1 = getSecretKeyForPBKDF2(algoToTest);136SecretKey key2 = getMyOwnSecretKey();137138// Is it actually the same?139if (!Arrays.equals(key1.getEncoded(), key2.getEncoded())) {140System.err.println("We shouldn't be here. The key1 and key2 values "141+ "in its primary encoding format have to be the same!");142return false;143}144145// Translate key146SecretKeyFactory skf = SecretKeyFactory.getInstance(algoToTest);147SecretKey key3 = skf.translateKey(key2);148149// Check if it still the same after translation150if (!Arrays.equals(key1.getEncoded(), key3.getEncoded())) {151System.err.println("testMyOwnSecretKey test case failed: the key1 "152+ "and key3 values in its primary encoding format are not "153+ "the same for " + algoToTest + "algorithm.");154return false;155}156157return true;158}159160/**161* The test case scenario implemented in the method: - create my own secret162* Key2 as an instance of a class implements PBEKey - spoil the key (set163* iteration count to 0, for example) - try to translate key -164* InvalidKeyException is expected.165*166* @return true if InvalidKeyException occurred; false - otherwise.167* @throws NoSuchAlgorithmException168* @throws InvalidKeySpecException169*/170public boolean translateSpoiledKey() throws NoSuchAlgorithmException,171InvalidKeySpecException {172// derive the key173SecretKey key1 = getMyOwnSecretKey();174175// spoil the key176((MyPBKDF2SecretKey) key1).spoil();177178// translate key179SecretKeyFactory skf = SecretKeyFactory.getInstance(algoToTest);180try {181SecretKey key2 = skf.translateKey(key1);182} catch (InvalidKeyException ike) {183// this is expected184return true;185}186187return false;188}189190/**191* Generate a PBKDF2 secret key using given algorithm.192*193* @param algoToDeriveKey PBKDF2 algorithm194* @return PBKDF2 secret key195* @throws NoSuchAlgorithmException196* @throws InvalidKeySpecException197*/198private SecretKey getSecretKeyForPBKDF2(String algoToDeriveKey)199throws NoSuchAlgorithmException, InvalidKeySpecException {200SecretKeyFactory skf = SecretKeyFactory.getInstance(algoToDeriveKey);201202PBEKeySpec spec = new PBEKeySpec(PASS_PHRASE.toCharArray(),203this.salt, ITERATION_COUNT, KEY_SIZE);204205return skf.generateSecret(spec);206}207208/**209* Generate a secrete key as an instance of a class implements PBEKey.210*211* @return secrete key212* @throws InvalidKeySpecException213* @throws NoSuchAlgorithmException214*/215private SecretKey getMyOwnSecretKey() throws InvalidKeySpecException,216NoSuchAlgorithmException {217return new MyPBKDF2SecretKey(PASS_PHRASE, this.algoToTest, this.salt,218ITERATION_COUNT, KEY_SIZE);219}220}221222/**223* An utility class to check the SecretKeyFactory.translateKey() method.224*/225class MyPBKDF2SecretKey implements PBEKey {226227private final byte[] key;228private final byte[] salt;229private final String algorithm;230private final int keySize, keyLength;231private int itereationCount;232private final String pass;233234@Override235public String getAlgorithm() {236return algorithm;237}238239@Override240public String getFormat() {241return "RAW";242}243244@Override245public byte[] getEncoded() {246byte[] copy = new byte[keyLength];247System.arraycopy(this.key, 0, copy, 0, keyLength);248return copy;249}250251/**252* The key is generating by SecretKeyFactory and its value just copying in253* the key field of MySecretKey class. So, this is real key derived using254* the given algorithm.255*256* @param passPhrase some string intended to be a password257* @param algo PBKDF2 algorithm258* @param salt slat for PBKDF2259* @param iterationCount iteration count260* @param keySize key size in bits261* @throws InvalidKeySpecException262* @throws NoSuchAlgorithmException263*/264public MyPBKDF2SecretKey(String passPhrase, String algo, byte[] salt,265int iterationCount, int keySize)266throws InvalidKeySpecException, NoSuchAlgorithmException {267this.algorithm = algo;268this.salt = salt;269this.itereationCount = iterationCount;270this.keySize = keySize;271this.pass = passPhrase;272273PBEKeySpec spec = new PBEKeySpec(passPhrase.toCharArray(),274this.salt, iterationCount, this.keySize);275276SecretKeyFactory keyFactory277= SecretKeyFactory.getInstance(algo);278279SecretKey realKey = keyFactory.generateSecret(spec);280281this.keyLength = realKey.getEncoded().length;282283this.key = new byte[this.keyLength];284System.arraycopy(realKey.getEncoded(), 0, this.key, 0,285this.keyLength);286}287288@Override289public int getIterationCount() {290return itereationCount;291}292293@Override294public byte[] getSalt() {295return salt;296}297298@Override299public char[] getPassword() {300return this.pass.toCharArray();301}302303/**304* Spoil the generated key (before translation) to cause an305* InvalidKeyException306*/307public void spoil() {308this.itereationCount = -1;309}310311}312313314