equal
deleted
inserted
replaced
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(), |