< prev index next >

src/java.base/share/classes/sun/security/provider/KeyProtector.java

Print this page


   1 /*
   2  * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   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
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.provider;
  27 
  28 import java.io.IOException;
  29 import java.io.UnsupportedEncodingException;
  30 import java.security.Key;
  31 import java.security.KeyStoreException;
  32 import java.security.MessageDigest;
  33 import java.security.NoSuchAlgorithmException;
  34 import java.security.SecureRandom;
  35 import java.security.UnrecoverableKeyException;
  36 import java.util.*;
  37 
  38 import jdk.internal.ref.CleanerFactory;
  39 import sun.security.pkcs.PKCS8Key;
  40 import sun.security.pkcs.EncryptedPrivateKeyInfo;
  41 import sun.security.x509.AlgorithmId;
  42 import sun.security.util.ObjectIdentifier;
  43 import sun.security.util.DerValue;
  44 
  45 /**
  46  * This is an implementation of a Sun proprietary, exportable algorithm
  47  * intended for use when protecting (or recovering the cleartext version of)
  48  * sensitive keys.
  49  * This algorithm is not intended as a general purpose cipher.
  50  *
  51  * This is how the algorithm works for key protection:
  52  *
  53  * p - user password
  54  * s - random salt
  55  * X - xor key
  56  * P - to-be-protected key
  57  * Y - protected key
  58  * R - what gets stored in the keystore


 103 
 104 final class KeyProtector {
 105 
 106     private static final int SALT_LEN = 20; // the salt length
 107     private static final String DIGEST_ALG = "SHA";
 108     private static final int DIGEST_LEN = 20;
 109 
 110     // defined by JavaSoft
 111     private static final String KEY_PROTECTOR_OID = "1.3.6.1.4.1.42.2.17.1.1";
 112 
 113     // The password used for protecting/recovering keys passed through this
 114     // key protector. We store it as a byte array, so that we can digest it.
 115     private byte[] passwdBytes;
 116 
 117     private MessageDigest md;
 118 
 119 
 120     /**
 121      * Creates an instance of this class, and initializes it with the given
 122      * password.
 123      *
 124      * <p>The password is expected to be in printable ASCII.
 125      * Normal rules for good password selection apply: at least
 126      * seven characters, mixed case, with punctuation encouraged.
 127      * Phrases or words which are easily guessed, for example by
 128      * being found in dictionaries, are bad.
 129      */
 130     public KeyProtector(char[] password)
 131         throws NoSuchAlgorithmException
 132     {
 133         int i, j;
 134 
 135         if (password == null) {
 136            throw new IllegalArgumentException("password can't be null");
 137         }
 138         md = MessageDigest.getInstance(DIGEST_ALG);
 139         // Convert password to byte array, so that it can be digested
 140         passwdBytes = new byte[password.length * 2];
 141         for (i=0, j=0; i<password.length; i++) {
 142             passwdBytes[j++] = (byte)(password[i] >> 8);
 143             passwdBytes[j++] = (byte)password[i];
 144         }
 145         // Use the cleaner to zero the password when no longer referenced
 146         final byte[] k = this.passwdBytes;
 147         CleanerFactory.cleaner().register(this,
 148                 () -> java.util.Arrays.fill(k, (byte)0x00));
 149     }
 150 
 151     /*
 152      * Protects the given plaintext key, using the password provided at
 153      * construction time.
 154      */
 155     public byte[] protect(Key key) throws KeyStoreException
 156     {
 157         int i;
 158         int numRounds;
 159         byte[] digest;
 160         int xorOffset; // offset in xorKey where next digest will be stored
 161         int encrKeyOffset = 0;
 162 
 163         if (key == null) {
 164             throw new IllegalArgumentException("plaintext key can't be null");
 165         }
 166 
 167         if (!"PKCS#8".equalsIgnoreCase(key.getFormat())) {
 168             throw new KeyStoreException(


   1 /*
   2  * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   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
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.provider;
  27 
  28 import java.io.IOException;
  29 import java.io.UnsupportedEncodingException;
  30 import java.security.Key;
  31 import java.security.KeyStoreException;
  32 import java.security.MessageDigest;
  33 import java.security.NoSuchAlgorithmException;
  34 import java.security.SecureRandom;
  35 import java.security.UnrecoverableKeyException;
  36 import java.util.*;
  37 

  38 import sun.security.pkcs.PKCS8Key;
  39 import sun.security.pkcs.EncryptedPrivateKeyInfo;
  40 import sun.security.x509.AlgorithmId;
  41 import sun.security.util.ObjectIdentifier;
  42 import sun.security.util.DerValue;
  43 
  44 /**
  45  * This is an implementation of a Sun proprietary, exportable algorithm
  46  * intended for use when protecting (or recovering the cleartext version of)
  47  * sensitive keys.
  48  * This algorithm is not intended as a general purpose cipher.
  49  *
  50  * This is how the algorithm works for key protection:
  51  *
  52  * p - user password
  53  * s - random salt
  54  * X - xor key
  55  * P - to-be-protected key
  56  * Y - protected key
  57  * R - what gets stored in the keystore


 102 
 103 final class KeyProtector {
 104 
 105     private static final int SALT_LEN = 20; // the salt length
 106     private static final String DIGEST_ALG = "SHA";
 107     private static final int DIGEST_LEN = 20;
 108 
 109     // defined by JavaSoft
 110     private static final String KEY_PROTECTOR_OID = "1.3.6.1.4.1.42.2.17.1.1";
 111 
 112     // The password used for protecting/recovering keys passed through this
 113     // key protector. We store it as a byte array, so that we can digest it.
 114     private byte[] passwdBytes;
 115 
 116     private MessageDigest md;
 117 
 118 
 119     /**
 120      * Creates an instance of this class, and initializes it with the given
 121      * password.






 122      */
 123     public KeyProtector(byte[] passwordBytes)
 124         throws NoSuchAlgorithmException
 125     {
 126         if (passwordBytes == null) {


 127            throw new IllegalArgumentException("password can't be null");
 128         }
 129         md = MessageDigest.getInstance(DIGEST_ALG);
 130         this.passwdBytes = passwordBytes;









 131     }
 132 
 133     /*
 134      * Protects the given plaintext key, using the password provided at
 135      * construction time.
 136      */
 137     public byte[] protect(Key key) throws KeyStoreException
 138     {
 139         int i;
 140         int numRounds;
 141         byte[] digest;
 142         int xorOffset; // offset in xorKey where next digest will be stored
 143         int encrKeyOffset = 0;
 144 
 145         if (key == null) {
 146             throw new IllegalArgumentException("plaintext key can't be null");
 147         }
 148 
 149         if (!"PKCS#8".equalsIgnoreCase(key.getFormat())) {
 150             throw new KeyStoreException(


< prev index next >