2727
2828import java .security .*;
2929import java .security .spec .*;
30- import java .util .Arrays ;
3130import javax .crypto .*;
3231import javax .crypto .spec .*;
3332
33+ import sun .security .util .PBEUtil ;
34+
3435/**
3536 * This class represents password-based encryption as defined by the PKCS #5
3637 * standard.
@@ -54,9 +55,8 @@ abstract class PBES2Core extends CipherSpi {
5455 private final PBKDF2Core kdf ;
5556 private final String pbeAlgo ;
5657 private final String cipherAlgo ;
57- private int iCount = DEFAULT_COUNT ;
58- private byte [] salt = null ;
59- private IvParameterSpec ivSpec = null ;
58+ private final PBEUtil .PBES2Helper pbes2Helper = new PBEUtil .PBES2Helper (
59+ DEFAULT_SALT_LENGTH , DEFAULT_COUNT );
6060
6161 /**
6262 * Creates an instance of PBE Scheme 2 according to the selected
@@ -129,32 +129,8 @@ protected byte[] engineGetIV() {
129129 }
130130
131131 protected AlgorithmParameters engineGetParameters () {
132- AlgorithmParameters params = null ;
133- if (salt == null ) {
134- // generate random salt and use default iteration count
135- salt = new byte [DEFAULT_SALT_LENGTH ];
136- SunJCE .getRandom ().nextBytes (salt );
137- iCount = DEFAULT_COUNT ;
138- }
139- if (ivSpec == null ) {
140- // generate random IV
141- byte [] ivBytes = new byte [blkSize ];
142- SunJCE .getRandom ().nextBytes (ivBytes );
143- ivSpec = new IvParameterSpec (ivBytes );
144- }
145- PBEParameterSpec pbeSpec = new PBEParameterSpec (salt , iCount , ivSpec );
146- try {
147- params = AlgorithmParameters .getInstance (pbeAlgo ,
148- SunJCE .getInstance ());
149- params .init (pbeSpec );
150- } catch (NoSuchAlgorithmException nsae ) {
151- // should never happen
152- throw new RuntimeException ("SunJCE called, but not configured" );
153- } catch (InvalidParameterSpecException ipse ) {
154- // should never happen
155- throw new RuntimeException ("PBEParameterSpec not supported" );
156- }
157- return params ;
132+ return pbes2Helper .getAlgorithmParameters (
133+ blkSize , pbeAlgo , SunJCE .getInstance (), SunJCE .getRandom ());
158134 }
159135
160136 protected void engineInit (int opmode , Key key , SecureRandom random )
@@ -174,105 +150,8 @@ protected void engineInit(int opmode, Key key,
174150 SecureRandom random )
175151 throws InvalidKeyException , InvalidAlgorithmParameterException {
176152
177- if (key == null ) {
178- throw new InvalidKeyException ("Null key" );
179- }
180-
181- byte [] passwdBytes = key .getEncoded ();
182- char [] passwdChars = null ;
183- PBEKeySpec pbeSpec ;
184- try {
185- if ((passwdBytes == null ) ||
186- !(key .getAlgorithm ().regionMatches (true , 0 , "PBE" , 0 , 3 ))) {
187- throw new InvalidKeyException ("Missing password" );
188- }
189-
190- // TBD: consolidate the salt, ic and IV parameter checks below
191-
192- // Extract salt and iteration count from the key, if present
193- if (key instanceof javax .crypto .interfaces .PBEKey ) {
194- salt = ((javax .crypto .interfaces .PBEKey )key ).getSalt ();
195- if (salt != null && salt .length < 8 ) {
196- throw new InvalidAlgorithmParameterException (
197- "Salt must be at least 8 bytes long" );
198- }
199- iCount = ((javax .crypto .interfaces .PBEKey )key ).getIterationCount ();
200- if (iCount == 0 ) {
201- iCount = DEFAULT_COUNT ;
202- } else if (iCount < 0 ) {
203- throw new InvalidAlgorithmParameterException (
204- "Iteration count must be a positive number" );
205- }
206- }
207-
208- // Extract salt, iteration count and IV from the params, if present
209- if (params == null ) {
210- if (salt == null ) {
211- // generate random salt and use default iteration count
212- salt = new byte [DEFAULT_SALT_LENGTH ];
213- random .nextBytes (salt );
214- iCount = DEFAULT_COUNT ;
215- }
216- if ((opmode == Cipher .ENCRYPT_MODE ) ||
217- (opmode == Cipher .WRAP_MODE )) {
218- // generate random IV
219- byte [] ivBytes = new byte [blkSize ];
220- random .nextBytes (ivBytes );
221- ivSpec = new IvParameterSpec (ivBytes );
222- }
223- } else {
224- if (!(params instanceof PBEParameterSpec )) {
225- throw new InvalidAlgorithmParameterException
226- ("Wrong parameter type: PBE expected" );
227- }
228- // salt and iteration count from the params take precedence
229- byte [] specSalt = ((PBEParameterSpec ) params ).getSalt ();
230- if (specSalt != null && specSalt .length < 8 ) {
231- throw new InvalidAlgorithmParameterException (
232- "Salt must be at least 8 bytes long" );
233- }
234- salt = specSalt ;
235- int specICount = ((PBEParameterSpec ) params ).getIterationCount ();
236- if (specICount == 0 ) {
237- specICount = DEFAULT_COUNT ;
238- } else if (specICount < 0 ) {
239- throw new InvalidAlgorithmParameterException (
240- "Iteration count must be a positive number" );
241- }
242- iCount = specICount ;
243-
244- AlgorithmParameterSpec specParams =
245- ((PBEParameterSpec ) params ).getParameterSpec ();
246- if (specParams != null ) {
247- if (specParams instanceof IvParameterSpec ) {
248- ivSpec = (IvParameterSpec )specParams ;
249- } else {
250- throw new InvalidAlgorithmParameterException (
251- "Wrong parameter type: IV expected" );
252- }
253- } else if ((opmode == Cipher .ENCRYPT_MODE ) ||
254- (opmode == Cipher .WRAP_MODE )) {
255- // generate random IV
256- byte [] ivBytes = new byte [blkSize ];
257- random .nextBytes (ivBytes );
258- ivSpec = new IvParameterSpec (ivBytes );
259- } else {
260- throw new InvalidAlgorithmParameterException (
261- "Missing parameter type: IV expected" );
262- }
263- }
264-
265- passwdChars = new char [passwdBytes .length ];
266- for (int i = 0 ; i < passwdChars .length ; i ++)
267- passwdChars [i ] = (char ) (passwdBytes [i ] & 0x7f );
268-
269- pbeSpec = new PBEKeySpec (passwdChars , salt , iCount , keyLength );
270- // password char[] was cloned in PBEKeySpec constructor,
271- // so we can zero it out here
272- } finally {
273- if (passwdChars != null ) Arrays .fill (passwdChars , '\0' );
274- if (passwdBytes != null ) Arrays .fill (passwdBytes , (byte )0x00 );
275- }
153+ PBEKeySpec pbeSpec = pbes2Helper .getPBEKeySpec (blkSize , keyLength ,
154+ opmode , key , params , random );
276155
277156 PBKDF2KeyImpl s ;
278157
@@ -291,22 +170,14 @@ protected void engineInit(int opmode, Key key,
291170 SecretKeySpec cipherKey = new SecretKeySpec (derivedKey , cipherAlgo );
292171
293172 // initialize the underlying cipher
294- cipher .init (opmode , cipherKey , ivSpec , random );
173+ cipher .init (opmode , cipherKey , pbes2Helper . getIvSpec () , random );
295174 }
296175
297176 protected void engineInit (int opmode , Key key , AlgorithmParameters params ,
298177 SecureRandom random )
299178 throws InvalidKeyException , InvalidAlgorithmParameterException {
300- AlgorithmParameterSpec pbeSpec = null ;
301- if (params != null ) {
302- try {
303- pbeSpec = params .getParameterSpec (PBEParameterSpec .class );
304- } catch (InvalidParameterSpecException ipse ) {
305- throw new InvalidAlgorithmParameterException (
306- "Wrong parameter type: PBE expected" );
307- }
308- }
309- engineInit (opmode , key , pbeSpec , random );
179+ engineInit (opmode , key , PBEUtil .PBES2Helper .getParameterSpec (params ),
180+ random );
310181 }
311182
312183 protected byte [] engineUpdate (byte [] input , int inputOffset , int inputLen ) {
0 commit comments