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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package com.sun.crypto.provider;
27
28 import java.io.*;
29 import java.nio.ByteBuffer;
30 import java.nio.CharBuffer;
31 import java.nio.charset.Charset;
32 import java.util.Arrays;
33 import java.security.KeyRep;
34 import java.security.GeneralSecurityException;
35 import java.security.InvalidKeyException;
36 import java.security.NoSuchAlgorithmException;
37 import java.security.spec.InvalidKeySpecException;
38 import javax.crypto.Mac;
39 import javax.crypto.SecretKey;
40 import javax.crypto.spec.PBEKeySpec;
41 import javax.crypto.spec.SecretKeySpec;
42
43 /**
44 * This class represents a PBE key derived using PBKDF2 defined
45 * in PKCS#5 v2.0. meaning that
46 * 1) the password must consist of characters which will be converted
47 * to bytes using UTF-8 character encoding.
48 * 2) salt, iteration count, and to be derived key length are supplied
49 *
50 * @author Valerie Peng
51 *
52 */
53 final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
54
55 static final long serialVersionUID = -2234868909660948157L;
56
90 // Convert the password from char[] to byte[]
91 byte[] passwdBytes = getPasswordBytes(this.passwd);
92
93 this.salt = keySpec.getSalt();
94 if (salt == null) {
95 throw new InvalidKeySpecException("Salt not found");
96 }
97 this.iterCount = keySpec.getIterationCount();
98 if (iterCount == 0) {
99 throw new InvalidKeySpecException("Iteration count not found");
100 } else if (iterCount < 0) {
101 throw new InvalidKeySpecException("Iteration count is negative");
102 }
103 int keyLength = keySpec.getKeyLength();
104 if (keyLength == 0) {
105 throw new InvalidKeySpecException("Key length not found");
106 } else if (keyLength == 0) {
107 throw new InvalidKeySpecException("Key length is negative");
108 }
109 try {
110 this.prf = Mac.getInstance(prfAlgo, new SunJCE());
111 } catch (NoSuchAlgorithmException nsae) {
112 // not gonna happen; re-throw just in case
113 InvalidKeySpecException ike = new InvalidKeySpecException();
114 ike.initCause(nsae);
115 throw ike;
116 }
117 this.key = deriveKey(prf, passwdBytes, salt, iterCount, keyLength);
118 }
119
120 private static byte[] deriveKey(Mac prf, byte[] password, byte[] salt,
121 int iterCount, int keyLengthInBit) {
122 int keyLength = keyLengthInBit/8;
123 byte[] key = new byte[keyLength];
124 try {
125 int hlen = prf.getMacLength();
126 int intL = (keyLength + hlen - 1)/hlen; // ceiling
127 int intR = keyLength - (intL - 1)*hlen; // residue
128 byte[] ui = new byte[hlen];
129 byte[] ti = new byte[hlen];
130 SecretKey macKey = new SecretKeySpec(password, prf.getAlgorithm());
|
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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package com.sun.crypto.provider;
27
28 import java.io.*;
29 import java.nio.ByteBuffer;
30 import java.nio.CharBuffer;
31 import java.nio.charset.Charset;
32 import java.util.Arrays;
33 import java.security.KeyRep;
34 import java.security.GeneralSecurityException;
35 import java.security.InvalidKeyException;
36 import java.security.NoSuchAlgorithmException;
37 import java.security.NoSuchProviderException;
38 import java.security.spec.InvalidKeySpecException;
39 import javax.crypto.Mac;
40 import javax.crypto.SecretKey;
41 import javax.crypto.spec.PBEKeySpec;
42 import javax.crypto.spec.SecretKeySpec;
43
44 /**
45 * This class represents a PBE key derived using PBKDF2 defined
46 * in PKCS#5 v2.0. meaning that
47 * 1) the password must consist of characters which will be converted
48 * to bytes using UTF-8 character encoding.
49 * 2) salt, iteration count, and to be derived key length are supplied
50 *
51 * @author Valerie Peng
52 *
53 */
54 final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
55
56 static final long serialVersionUID = -2234868909660948157L;
57
91 // Convert the password from char[] to byte[]
92 byte[] passwdBytes = getPasswordBytes(this.passwd);
93
94 this.salt = keySpec.getSalt();
95 if (salt == null) {
96 throw new InvalidKeySpecException("Salt not found");
97 }
98 this.iterCount = keySpec.getIterationCount();
99 if (iterCount == 0) {
100 throw new InvalidKeySpecException("Iteration count not found");
101 } else if (iterCount < 0) {
102 throw new InvalidKeySpecException("Iteration count is negative");
103 }
104 int keyLength = keySpec.getKeyLength();
105 if (keyLength == 0) {
106 throw new InvalidKeySpecException("Key length not found");
107 } else if (keyLength == 0) {
108 throw new InvalidKeySpecException("Key length is negative");
109 }
110 try {
111 this.prf = Mac.getInstance(prfAlgo);
112 } catch (NoSuchAlgorithmException nsae) {
113 // not gonna happen; re-throw just in case
114 InvalidKeySpecException ike = new InvalidKeySpecException();
115 ike.initCause(nsae);
116 throw ike;
117 }
118 this.key = deriveKey(prf, passwdBytes, salt, iterCount, keyLength);
119 }
120
121 private static byte[] deriveKey(Mac prf, byte[] password, byte[] salt,
122 int iterCount, int keyLengthInBit) {
123 int keyLength = keyLengthInBit/8;
124 byte[] key = new byte[keyLength];
125 try {
126 int hlen = prf.getMacLength();
127 int intL = (keyLength + hlen - 1)/hlen; // ceiling
128 int intR = keyLength - (intL - 1)*hlen; // residue
129 byte[] ui = new byte[hlen];
130 byte[] ti = new byte[hlen];
131 SecretKey macKey = new SecretKeySpec(password, prf.getAlgorithm());
|