src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java
changeset 47417 5984d1c9d03d
parent 47216 71c04702a3d5
child 49783 977c6dd636bd
equal deleted inserted replaced
47416:a627f88bed3a 47417:5984d1c9d03d
     1 /*
     1 /*
     2  * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    36 import java.security.GeneralSecurityException;
    36 import java.security.GeneralSecurityException;
    37 import java.security.NoSuchAlgorithmException;
    37 import java.security.NoSuchAlgorithmException;
    38 import java.security.NoSuchProviderException;
    38 import java.security.NoSuchProviderException;
    39 import java.security.UnrecoverableKeyException;
    39 import java.security.UnrecoverableKeyException;
    40 import java.security.AlgorithmParameters;
    40 import java.security.AlgorithmParameters;
       
    41 import java.security.spec.InvalidParameterSpecException;
    41 import java.security.spec.PKCS8EncodedKeySpec;
    42 import java.security.spec.PKCS8EncodedKeySpec;
    42 
    43 
    43 import javax.crypto.Cipher;
    44 import javax.crypto.Cipher;
    44 import javax.crypto.CipherSpi;
    45 import javax.crypto.CipherSpi;
    45 import javax.crypto.SecretKey;
    46 import javax.crypto.SecretKey;
    72 
    73 
    73     // JavaSoft proprietary key-protection algorithm (used to protect private
    74     // JavaSoft proprietary key-protection algorithm (used to protect private
    74     // keys in the keystore implementation that comes with JDK 1.2)
    75     // keys in the keystore implementation that comes with JDK 1.2)
    75     private static final String KEY_PROTECTOR_OID = "1.3.6.1.4.1.42.2.17.1.1";
    76     private static final String KEY_PROTECTOR_OID = "1.3.6.1.4.1.42.2.17.1.1";
    76 
    77 
       
    78     private static final int MAX_ITERATION_COUNT = 5000000;
       
    79     private static final int ITERATION_COUNT = 200000;
    77     private static final int SALT_LEN = 20; // the salt length
    80     private static final int SALT_LEN = 20; // the salt length
    78     private static final int DIGEST_LEN = 20;
    81     private static final int DIGEST_LEN = 20;
    79 
    82 
    80     // the password used for protecting/recovering keys passed through this
    83     // the password used for protecting/recovering keys passed through this
    81     // key protector
    84     // key protector
    98         // create a random salt (8 bytes)
   101         // create a random salt (8 bytes)
    99         byte[] salt = new byte[8];
   102         byte[] salt = new byte[8];
   100         SunJCE.getRandom().nextBytes(salt);
   103         SunJCE.getRandom().nextBytes(salt);
   101 
   104 
   102         // create PBE parameters from salt and iteration count
   105         // create PBE parameters from salt and iteration count
   103         PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
   106         PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, ITERATION_COUNT);
   104 
   107 
   105         // create PBE key from password
   108         // create PBE key from password
   106         PBEKeySpec pbeKeySpec = new PBEKeySpec(this.password);
   109         PBEKeySpec pbeKeySpec = new PBEKeySpec(this.password);
   107         SecretKey sKey = new PBEKey(pbeKeySpec, "PBEWithMD5AndTripleDES");
   110         SecretKey sKey = new PBEKey(pbeKeySpec, "PBEWithMD5AndTripleDES");
   108         pbeKeySpec.clearPassword();
   111         pbeKeySpec.clearPassword();
   153                 AlgorithmParameters pbeParams =
   156                 AlgorithmParameters pbeParams =
   154                     AlgorithmParameters.getInstance("PBE");
   157                     AlgorithmParameters.getInstance("PBE");
   155                 pbeParams.init(encodedParams);
   158                 pbeParams.init(encodedParams);
   156                 PBEParameterSpec pbeSpec =
   159                 PBEParameterSpec pbeSpec =
   157                         pbeParams.getParameterSpec(PBEParameterSpec.class);
   160                         pbeParams.getParameterSpec(PBEParameterSpec.class);
       
   161                 if (pbeSpec.getIterationCount() > MAX_ITERATION_COUNT) {
       
   162                     throw new IOException("PBE iteration count too large");
       
   163                 }
   158 
   164 
   159                 // create PBE key from password
   165                 // create PBE key from password
   160                 PBEKeySpec pbeKeySpec = new PBEKeySpec(this.password);
   166                 PBEKeySpec pbeKeySpec = new PBEKeySpec(this.password);
   161                 SecretKey sKey =
   167                 SecretKey sKey =
   162                     new PBEKey(pbeKeySpec, "PBEWithMD5AndTripleDES");
   168                     new PBEKey(pbeKeySpec, "PBEWithMD5AndTripleDES");
   283         // create a random salt (8 bytes)
   289         // create a random salt (8 bytes)
   284         byte[] salt = new byte[8];
   290         byte[] salt = new byte[8];
   285         SunJCE.getRandom().nextBytes(salt);
   291         SunJCE.getRandom().nextBytes(salt);
   286 
   292 
   287         // create PBE parameters from salt and iteration count
   293         // create PBE parameters from salt and iteration count
   288         PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
   294         PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, ITERATION_COUNT);
   289 
   295 
   290         // create PBE key from password
   296         // create PBE key from password
   291         PBEKeySpec pbeKeySpec = new PBEKeySpec(this.password);
   297         PBEKeySpec pbeKeySpec = new PBEKeySpec(this.password);
   292         SecretKey sKey = new PBEKey(pbeKeySpec, "PBEWithMD5AndTripleDES");
   298         SecretKey sKey = new PBEKey(pbeKeySpec, "PBEWithMD5AndTripleDES");
   293         pbeKeySpec.clearPassword();
   299         pbeKeySpec.clearPassword();
   323             }
   329             }
   324             AlgorithmParameters params = soForKeyProtector.getParameters();
   330             AlgorithmParameters params = soForKeyProtector.getParameters();
   325             if (params == null) {
   331             if (params == null) {
   326                 throw new UnrecoverableKeyException("Cannot get " +
   332                 throw new UnrecoverableKeyException("Cannot get " +
   327                                                     "algorithm parameters");
   333                                                     "algorithm parameters");
       
   334             }
       
   335             PBEParameterSpec pbeSpec;
       
   336             try {
       
   337                 pbeSpec = params.getParameterSpec(PBEParameterSpec.class);
       
   338             } catch (InvalidParameterSpecException ipse) {
       
   339                 throw new IOException("Invalid PBE algorithm parameters");
       
   340             }
       
   341             if (pbeSpec.getIterationCount() > MAX_ITERATION_COUNT) {
       
   342                 throw new IOException("PBE iteration count too large");
   328             }
   343             }
   329             PBEWithMD5AndTripleDESCipher cipherSpi;
   344             PBEWithMD5AndTripleDESCipher cipherSpi;
   330             cipherSpi = new PBEWithMD5AndTripleDESCipher();
   345             cipherSpi = new PBEWithMD5AndTripleDESCipher();
   331             Cipher cipher = new CipherForKeyProtector(cipherSpi,
   346             Cipher cipher = new CipherForKeyProtector(cipherSpi,
   332                                                       SunJCE.getInstance(),
   347                                                       SunJCE.getInstance(),