11/*
2- * Copyright (c) 2002, 2024 , Oracle and/or its affiliates. All rights reserved.
2+ * Copyright (c) 2002, 2025 , Oracle and/or its affiliates. All rights reserved.
33 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44 *
55 * This code is free software; you can redistribute it and/or modify it
@@ -50,6 +50,36 @@ final class PBES1Core {
5050 // RFC 8018 and NIST SP 800-132 sec 5.2 recommend 1000 as the minimum
5151 private int iCount = PKCS12PBECipherCore .DEFAULT_COUNT ;
5252
53+ // utility method for checking weak salts of PBEWithMD5AndTripleDES cipher
54+ private static boolean isWeak (byte [] s ) {
55+ // consider salts weak if it met both of the following conditions:
56+ // 1) s[0...3] == s[4...7]
57+ // 2) s[0] == s[3] && s[1] == s[2]
58+ if (Arrays .equals (s , 0 , 4 , s , 4 , 8 )) {
59+ return (s [0 ] == s [3 ]) && (s [1 ] == s [2 ]);
60+ }
61+ return false ;
62+ }
63+
64+ // utility method for generating 8-byte salts
65+ private static byte [] generateSalt (String algo , SecureRandom sr ) {
66+ byte [] salt = new byte [8 ];
67+ sr .nextBytes (salt );
68+ // check and re-generate for DESede if necessary
69+ if (algo .equals ("DESede" )) {
70+ // prevent an infinite-loop in case of a rigged SecureRandom
71+ int numAttempts = 50 ;
72+ while (isWeak (salt )) {
73+ sr .nextBytes (salt );
74+ if (numAttempts -- < 0 ) {
75+ throw new ProviderException (
76+ "Unable to find salts after 50 attempts" );
77+ }
78+ }
79+ }
80+ return salt ;
81+ }
82+
5383 /**
5484 * Creates an instance of PBE Cipher using the specified CipherSpi
5585 * instance.
@@ -164,8 +194,7 @@ byte[] getIV() {
164194 AlgorithmParameters getParameters () {
165195 AlgorithmParameters params ;
166196 if (salt == null ) {
167- salt = new byte [8 ];
168- SunJCE .getRandom ().nextBytes (salt );
197+ salt = generateSalt (algo , SunJCE .getRandom ());
169198 }
170199 PBEParameterSpec pbeSpec = new PBEParameterSpec (salt , iCount );
171200 try {
@@ -228,8 +257,7 @@ void init(int opmode, Key key, AlgorithmParameterSpec params,
228257
229258 if (params == null ) {
230259 // create random salt and use default iteration count
231- salt = new byte [8 ];
232- random .nextBytes (salt );
260+ salt = generateSalt (algo , random );
233261 } else {
234262 if (!(params instanceof PBEParameterSpec )) {
235263 throw new InvalidAlgorithmParameterException
@@ -241,6 +269,15 @@ void init(int opmode, Key key, AlgorithmParameterSpec params,
241269 throw new InvalidAlgorithmParameterException
242270 ("Salt must be 8 bytes long" );
243271 }
272+ // for DESede, reject weak salts for encryption
273+ if (algo .equals ("DESede" ) &&
274+ (opmode == Cipher .ENCRYPT_MODE ||
275+ opmode == Cipher .WRAP_MODE ) &&
276+ isWeak (salt )) {
277+ throw new InvalidAlgorithmParameterException (
278+ "Weak salts cannot be used for encryption" );
279+ }
280+
244281 iCount = ((PBEParameterSpec ) params ).getIterationCount ();
245282 if (iCount <= 0 ) {
246283 throw new InvalidAlgorithmParameterException
0 commit comments