Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/security/tools/keytool/StorePasswords.java
38853 views
/*1* Copyright (c) 2013, 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*/2223/*24* @test25* @bug 800829626* @summary Store and retrieve user passwords using PKCS#12 keystore27*/2829import java.io.*;30import java.security.*;31import java.util.*;32import javax.crypto.*;33import javax.crypto.spec.*;3435/*36* Store and retrieve passwords protected by a selection of PBE algorithms,37* using a PKCS#12 keystore.38*/39public class StorePasswords {4041private static final String[] PBE_ALGORITHMS = new String[] {42"default PBE algorithm",43"PBEWithMD5AndDES",44"PBEWithSHA1AndDESede",45"PBEWithSHA1AndRC2_40",46"PBEWithSHA1AndRC2_128",47"PBEWithSHA1AndRC4_40",48"PBEWithSHA1AndRC4_128",49"PBEWithHmacSHA1AndAES_128",50"PBEWithHmacSHA224AndAES_128",51"PBEWithHmacSHA256AndAES_128",52"PBEWithHmacSHA384AndAES_128",53"PBEWithHmacSHA512AndAES_128",54"PBEWithHmacSHA1AndAES_256",55"PBEWithHmacSHA224AndAES_256",56"PBEWithHmacSHA256AndAES_256",57"PBEWithHmacSHA384AndAES_256",58"PBEWithHmacSHA512AndAES_256"59};6061private static final String KEYSTORE = "mykeystore.p12";62private static final char[] KEYSTORE_PWD = "changeit".toCharArray();63private static final char[] ENTRY_PWD = "protectit".toCharArray();64private static final char[] USER_PWD = "hello1".toCharArray();6566public static void main(String[] args) throws Exception {6768new File(KEYSTORE).delete();6970int storeCount = store();71int recoverCount = recover();7273if (recoverCount != storeCount) {74throw new Exception("Stored " + storeCount + " user passwords, " +75"recovered " + recoverCount + " user passwords");76}77System.out.println("\nStored " + storeCount + " user passwords, " +78"recovered " + recoverCount + " user passwords");7980new File(KEYSTORE).delete();81}8283private static int store() throws Exception {84int count = 0;85// Load an empty PKCS#12 keystore86KeyStore keystore = KeyStore.getInstance("PKCS12");87System.out.println("\nLoading PKCS#12 keystore...");88keystore.load(null, null);8990// Derive a PBE key from the password91PBEKeySpec keySpec = new PBEKeySpec(USER_PWD);92SecretKeyFactory factory = SecretKeyFactory.getInstance("PBE");93SecretKey key = factory.generateSecret(keySpec);94PBEParameterSpec specWithEightByteSalt =95new PBEParameterSpec("NaClNaCl".getBytes(), 1024);9697// Store the user password in a keystore entry (for each algorithm)98for (String algorithm : PBE_ALGORITHMS) {99100try {101System.out.println("Storing user password '" +102new String(USER_PWD) + "' (protected by " + algorithm +103")");104105if (algorithm.equals("default PBE algorithm")) {106keystore.setKeyEntry(107"this entry is protected by " + algorithm, key,108ENTRY_PWD, null);109} else {110keystore.setEntry(111"this entry is protected by " + algorithm,112new KeyStore.SecretKeyEntry(key),113new KeyStore.PasswordProtection(ENTRY_PWD, algorithm,114null));115}116count++;117118} catch (KeyStoreException e) {119Throwable inner = e.getCause();120if (inner instanceof UnrecoverableKeyException) {121Throwable inner2 = inner.getCause();122if (inner2 instanceof InvalidAlgorithmParameterException) {123System.out.println("...re-trying due to: " +124inner2.getMessage());125126// Some PBE algorithms demand an 8-byte salt127keystore.setEntry(128"this entry is protected by " + algorithm,129new KeyStore.SecretKeyEntry(key),130new KeyStore.PasswordProtection(ENTRY_PWD,131algorithm, specWithEightByteSalt));132count++;133134} else if (inner2 instanceof InvalidKeyException) {135System.out.println("...skipping due to: " +136inner2.getMessage());137// Unsupported crypto keysize138continue;139}140} else {141throw e;142}143}144}145146// Store the PKCS#12 keystore147System.out.println("Storing PKCS#12 keystore to: " + KEYSTORE);148try (FileOutputStream out = new FileOutputStream(KEYSTORE)) {149keystore.store(out, KEYSTORE_PWD);150}151152return count;153}154155private static int recover() throws Exception {156int count = 0;157// Load the PKCS#12 keystore158KeyStore keystore = KeyStore.getInstance("PKCS12");159System.out.println("\nLoading PKCS#12 keystore from: " + KEYSTORE);160try (FileInputStream in = new FileInputStream(KEYSTORE)) {161keystore.load(in, KEYSTORE_PWD);162}163164SecretKey key;165SecretKeyFactory factory;166PBEKeySpec keySpec;167168// Retrieve each user password from the keystore169for (String algorithm : PBE_ALGORITHMS) {170key = (SecretKey) keystore.getKey("this entry is protected by " +171algorithm, ENTRY_PWD);172173if (key != null) {174count++;175factory = SecretKeyFactory.getInstance(key.getAlgorithm());176keySpec =177(PBEKeySpec) factory.getKeySpec(key, PBEKeySpec.class);178char[] pwd = keySpec.getPassword();179System.out.println("Recovered user password '" +180new String(pwd) + "' (protected by " + algorithm + ")");181182if (!Arrays.equals(USER_PWD, pwd)) {183throw new Exception("Failed to recover the user password " +184"protected by " + algorithm);185}186}187}188189return count;190}191}192193194