Path: blob/master/test/jdk/javax/crypto/SecretKeyFactory/PBKDF2TranslateTest.java
41149 views
/*1* Copyright (c) 2003, 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.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;32import javax.security.auth.DestroyFailedException;3334import static java.lang.System.out;3536/*37* @test38* @bug 804882039* @summary The test verifies if the SecretKeyFactory.translateKey() method40* works as expected for the PBKDF2 algorithms.41*/4243public class PBKDF2TranslateTest {4445private static final String PASS_PHRASE = "some hidden string";46private static final int ITERATION_COUNT = 1000;47private static final int KEY_SIZE = 128;48private static final String[] TEST_ALGOS = { "PBKDF2WithHmacSHA1",49"PBKDF2WithHmacSHA224", "PBKDF2WithHmacSHA256",50"PBKDF2WithHmacSHA384", "PBKDF2WithHmacSHA512" };51private final String algoForTest;5253public static void main(String[] args) throws Exception {54for (String algo : TEST_ALGOS) {55PBKDF2TranslateTest theTest = new PBKDF2TranslateTest(algo);56byte[] salt = new byte[8];57new Random().nextBytes(salt);58theTest.testMyOwnSecretKey(salt);59theTest.generateAndTranslateKey(salt);60theTest.translateSpoiledKey(salt);61}62}6364public PBKDF2TranslateTest(String algo) {65algoForTest = algo;66}6768/**69* The test case scenario implemented in the method: - derive PBKDF2 key70* using the given algorithm; - translate the key - check if the translated71* and original keys have the same key value.72*73*/74public void generateAndTranslateKey(byte[] salt)75throws NoSuchAlgorithmException, InvalidKeySpecException,76InvalidKeyException {77// derive PBKDF2 key78SecretKey key1 = getSecretKeyForPBKDF2(algoForTest, salt);7980// translate key81SecretKeyFactory skf = SecretKeyFactory.getInstance(algoForTest);82SecretKey key2 = skf.translateKey(key1);8384// Check if it still the same after translation85if (!Arrays.equals(key1.getEncoded(), key2.getEncoded())) {86System.out.println("Key1=" + new String(key1.getEncoded())87+ " key2=" + new String(key2.getEncoded()) + " salt="88+ new String(salt));89throw new RuntimeException(90"generateAndTranslateKey test case failed: the key1 and"91+ " key2 values in its primary encoding format are"92+ " not the same for " + algoForTest93+ " algorithm.");94}95}9697/**98* The test case scenario implemented in the method: - derive Key1 for the99* given PBKDF2 algorithm - create my own secret Key2 as an instance of a100* class implements PBEKey - translate Key2 - check if the key value of the101* translated key and Key1 are the same.102*/103private void testMyOwnSecretKey(byte[] salt)104throws NoSuchAlgorithmException, InvalidKeySpecException,105InvalidKeyException {106SecretKey key1 = getSecretKeyForPBKDF2(algoForTest, salt);107SecretKey key2 = getMyOwnSecretKey(salt);108109// Is it actually the same?110if (!Arrays.equals(key1.getEncoded(), key2.getEncoded())) {111throw new RuntimeException(112"We shouldn't be here. The key1 and key2 values in its"113+ " primary encoding format have to be the same!");114}115116// translate key117SecretKeyFactory skf = SecretKeyFactory.getInstance(algoForTest);118SecretKey key3 = skf.translateKey(key2);119120// Check if it still the same after translation121if (!Arrays.equals(key1.getEncoded(), key3.getEncoded())) {122System.out.println("Key1=" + new String(key1.getEncoded())123+ " key3=" + new String(key3.getEncoded()) + " salt="124+ new String(salt));125throw new RuntimeException(126"testMyOwnSecretKey test case failed: the key1 and key3"127+ " values in its primary encoding format are not"128+ " the same for " + algoForTest + " algorithm.");129}130131}132133/**134* The test case scenario implemented in the method: - create my own secret135* Key2 as an instance of a class implements PBEKey - spoil the key (set136* iteration count to 0, for example) - try to translate key -137* InvalidKeyException is expected.138*/139public void translateSpoiledKey(byte[] salt)140throws NoSuchAlgorithmException, InvalidKeySpecException {141// derive the key142SecretKey key1 = getMyOwnSecretKey(salt);143144// spoil the key145((MyPBKDF2SecretKey) key1).spoil();146147// translate key148SecretKeyFactory skf = SecretKeyFactory.getInstance(algoForTest);149try {150skf.translateKey(key1);151throw new RuntimeException(152"translateSpoiledKey test case failed, should throw"153+ " InvalidKeyException when spoil the key");154} catch (InvalidKeyException ike) {155out.println("Expected exception when spoil the key");156}157158}159160/**161* Generate a PBKDF2 secret key using given algorithm.162*/163private SecretKey getSecretKeyForPBKDF2(String algoDeriveKey, byte[] salt)164throws NoSuchAlgorithmException, InvalidKeySpecException {165166SecretKeyFactory skf = SecretKeyFactory.getInstance(algoDeriveKey);167PBEKeySpec spec = new PBEKeySpec(PASS_PHRASE.toCharArray(), salt,168ITERATION_COUNT, KEY_SIZE);169170return skf.generateSecret(spec);171}172173/**174* Generate a secrete key as an instance of a class implements PBEKey.175*/176private SecretKey getMyOwnSecretKey(byte[] salt)177throws InvalidKeySpecException, NoSuchAlgorithmException {178return new MyPBKDF2SecretKey(PASS_PHRASE, algoForTest, salt,179ITERATION_COUNT, KEY_SIZE);180}181182/**183* An utility class to check the SecretKeyFactory.translateKey() method.184*/185class MyPBKDF2SecretKey implements PBEKey {186private final byte[] key;187private final byte[] salt;188private final String algorithm;189private final int keyLength;190private final String pass;191private int itereationCount;192193/**194* The key is generating by SecretKeyFactory and its value just copying195* in the key field of MySecretKey class. So, this is real key derived196* using the given algo.197*/198public MyPBKDF2SecretKey(String passPhrase, String algo, byte[] salt1,199int iterationCount, int keySize)200throws InvalidKeySpecException, NoSuchAlgorithmException {201algorithm = algo;202salt = salt1;203itereationCount = iterationCount;204pass = passPhrase;205206PBEKeySpec spec = new PBEKeySpec(passPhrase.toCharArray(), salt,207iterationCount, keySize);208209SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algo);210211SecretKey realKey = keyFactory.generateSecret(spec);212213keyLength = realKey.getEncoded().length;214215key = new byte[keyLength];216System.arraycopy(realKey.getEncoded(), 0, key, 0, keyLength);217}218219@Override220public String getAlgorithm() {221return algorithm;222}223224@Override225public String getFormat() {226return "RAW";227}228229@Override230public byte[] getEncoded() {231byte[] copy = new byte[keyLength];232System.arraycopy(key, 0, copy, 0, keyLength);233return copy;234}235236@Override237public int getIterationCount() {238return itereationCount;239}240241@Override242public byte[] getSalt() {243return salt;244}245246@Override247public char[] getPassword() {248return pass.toCharArray();249}250251/**252* Spoil the generated key (before translation) to cause an253* InvalidKeyException254*/255public void spoil() {256itereationCount = -1;257}258259@Override260public void destroy() throws DestroyFailedException {261}262263@Override264public boolean isDestroyed() {265return false;266}267268}269}270271272