This is an automated email from the ASF dual-hosted git repository. jacopoc pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
commit bfaf39790de277e1674789b648fe7483c0235407 Author: Jacopo Cappellato <[email protected]> AuthorDate: Wed Sep 30 12:06:59 2026 +0200 Remove outdated DesCrypt implementation Remove the obsolete DesCrypt class and all references to it, as it relied on outdated and potentially insecure cryptographic algorithms. --- README.md | 2 +- .../org/apache/ofbiz/base/crypto/DesCrypt.java | 147 --------------------- .../java/org/apache/ofbiz/base/crypto/Main.java | 2 - .../org/apache/ofbiz/entity/util/EntityCrypto.java | 141 +------------------- .../ofbiz/entityext/data/EntityDataServices.java | 10 +- 5 files changed, 4 insertions(+), 298 deletions(-) diff --git a/README.md b/README.md index fbb8b8a201..b776be2f1b 100644 --- a/README.md +++ b/README.md @@ -858,7 +858,7 @@ source code. The following provides more details on the included cryptographic software: -* Various classes in OFBiz, including DesCrypt, HashCrypt, and BlowFishCrypt use +* Various classes in OFBiz, including HashCrypt, and BlowFishCrypt use libraries from the Sun Java JDK API including java.security.* and javax.crypto.* (the JCE, Java Cryptography Extensions API) * Other classes such as HttpClient and various related ones use the JSSE (Java diff --git a/framework/base/src/main/java/org/apache/ofbiz/base/crypto/DesCrypt.java b/framework/base/src/main/java/org/apache/ofbiz/base/crypto/DesCrypt.java deleted file mode 100644 index 02ddb9b270..0000000000 --- a/framework/base/src/main/java/org/apache/ofbiz/base/crypto/DesCrypt.java +++ /dev/null @@ -1,147 +0,0 @@ -/******************************************************************************* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - *******************************************************************************/ -package org.apache.ofbiz.base.crypto; - -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.Key; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.spec.InvalidKeySpecException; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.KeyGenerator; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.DESedeKeySpec; -import javax.crypto.spec.IvParameterSpec; - -import org.apache.commons.codec.binary.Base64; -import org.apache.ofbiz.base.util.GeneralException; - -/** - * Utility class for doing DESded (3DES) Two-Way Encryption - * - */ -public class DesCrypt { - - private static final SecureRandom SECURE_RANDOM = new SecureRandom(); - - public static Key generateKey() throws NoSuchAlgorithmException { - KeyGenerator keyGen = KeyGenerator.getInstance("DESede"); - - // generate the DES3 key - return keyGen.generateKey(); - } - - public static byte[] encrypt(Key key, byte[] bytes) throws GeneralException { - byte[] rawIv = new byte[8]; - SECURE_RANDOM.nextBytes(rawIv); - IvParameterSpec iv = new IvParameterSpec(rawIv); - - // Create the Cipher - DESede/CBC/PKCS5Padding - byte[] encBytes = null; - Cipher cipher = DesCrypt.getCipher(key, Cipher.ENCRYPT_MODE, iv); - try { - encBytes = cipher.doFinal(bytes); - } catch (IllegalStateException | IllegalBlockSizeException | BadPaddingException e) { - throw new GeneralException(e); - } - - // Prepend iv as a prefix to use it during decryption - byte[] combinedPayload = new byte[rawIv.length + encBytes.length]; - - // populate payload with prefix iv and encrypted data - System.arraycopy(iv, 0, combinedPayload, 0, rawIv.length); - System.arraycopy(cipher, 0, combinedPayload, 8, encBytes.length); - - return encBytes; - } - - public static byte[] decrypt(Key key, byte[] bytes) throws GeneralException { - // separate prefix with IV from the rest of encrypted data - byte[] encryptedPayload = Base64.decodeBase64(bytes); - byte[] iv = new byte[8]; - byte[] encryptedBytes = new byte[encryptedPayload.length - iv.length]; - - // populate iv with bytes: - System.arraycopy(encryptedPayload, 0, iv, 0, iv.length); - - // populate encryptedBytes with bytes: - System.arraycopy(encryptedPayload, iv.length, encryptedBytes, 0, encryptedBytes.length); - - byte[] decBytes = null; - Cipher cipher = DesCrypt.getCipher(key, Cipher.ENCRYPT_MODE, new IvParameterSpec(iv)); - try { - decBytes = cipher.doFinal(bytes); - } catch (IllegalStateException | IllegalBlockSizeException | BadPaddingException e) { - throw new GeneralException(e); - } - - return decBytes; - } - - public static Key getDesKey(byte[] rawKey) throws GeneralException { - SecretKeyFactory skf = null; - try { - skf = SecretKeyFactory.getInstance("DESede"); - } catch (NoSuchAlgorithmException e) { - throw new GeneralException(e); - } - - // load the raw key - if (rawKey.length > 0) { - DESedeKeySpec desedeSpec1 = null; - try { - desedeSpec1 = new DESedeKeySpec(rawKey); - } catch (InvalidKeyException e) { - throw new GeneralException(e); - } - - // create the SecretKey Object - Key key = null; - try { - key = skf.generateSecret(desedeSpec1); - } catch (InvalidKeySpecException e) { - throw new GeneralException(e); - } - return key; - } - throw new GeneralException("Not a valid DESede key!"); - } - - // return a cipher for a key - DESede/CBC/PKCS5Padding with random IV - protected static Cipher getCipher(Key key, int mode, IvParameterSpec iv) throws GeneralException { - // create the Cipher - DESede/CBC/PKCS5Padding - Cipher cipher = null; - try { - cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); - } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { - throw new GeneralException(e); - } - try { - cipher.init(mode, key, iv); - } catch (InvalidKeyException | InvalidAlgorithmParameterException e) { - throw new GeneralException(e); - } - return cipher; - } -} diff --git a/framework/base/src/main/java/org/apache/ofbiz/base/crypto/Main.java b/framework/base/src/main/java/org/apache/ofbiz/base/crypto/Main.java index 2f78722325..75d509ce76 100644 --- a/framework/base/src/main/java/org/apache/ofbiz/base/crypto/Main.java +++ b/framework/base/src/main/java/org/apache/ofbiz/base/crypto/Main.java @@ -33,8 +33,6 @@ public class Main { } else if ("-kek".equals(args[0])) { AesCipherService cs = new AesCipherService(); Debug.logInfo(Base64.encodeBase64String(cs.generateNewKey().getEncoded()), MODULE); - } else if ("-kek-old".equals(args[0])) { - Debug.logInfo(Base64.encodeBase64String(DesCrypt.generateKey().getEncoded()), MODULE); } } } diff --git a/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityCrypto.java b/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityCrypto.java index e52a2128f5..5618e41c16 100644 --- a/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityCrypto.java +++ b/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityCrypto.java @@ -19,18 +19,13 @@ package org.apache.ofbiz.entity.util; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.security.Key; -import java.security.NoSuchAlgorithmException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.commons.codec.binary.Base64; -import org.apache.ofbiz.base.crypto.DesCrypt; -import org.apache.ofbiz.base.crypto.HashCrypt; import org.apache.ofbiz.base.util.Debug; import org.apache.ofbiz.base.util.GeneralException; -import org.apache.ofbiz.base.util.StringUtil; import org.apache.ofbiz.base.util.UtilObject; import org.apache.ofbiz.base.util.UtilValidate; import org.apache.ofbiz.entity.Delegator; @@ -59,10 +54,7 @@ public final class EntityCrypto { byte[] kek; kek = UtilValidate.isNotEmpty(kekText) ? Base64.decodeBase64(kekText) : null; handlers = new StorageHandler[] { - new ShiroStorageHandler(kek), - new SaltedBase64StorageHandler(kek), - NORMAL_HASH_STORAGE_HANDLER, - OLD_FUNNY_HASH_STORAGE_HANDLER, + new ShiroStorageHandler(kek) }; } @@ -295,135 +287,4 @@ public final class EntityCrypto { return cipherService.encrypt(objBytes, key).toBase64(); } } - - protected abstract static class LegacyStorageHandler extends StorageHandler { - @Override - protected Key generateNewKey() throws EntityCryptoException { - try { - return DesCrypt.generateKey(); - } catch (NoSuchAlgorithmException e) { - throw new EntityCryptoException(e); - } - } - - @Override - protected byte[] decodeKeyBytes(String keyText) throws GeneralException { - return StringUtil.fromHexString(keyText); - } - - @Override - protected String encodeKey(byte[] key) { - return StringUtil.toHexString(key); - } - - @Override - protected byte[] decryptValue(byte[] key, EncryptMethod encryptMethod, String encryptedString) throws GeneralException { - return DesCrypt.decrypt(DesCrypt.getDesKey(key), StringUtil.fromHexString(encryptedString)); - } - - @Override - protected String encryptValue(EncryptMethod encryptMethod, byte[] key, byte[] objBytes) throws GeneralException { - return StringUtil.toHexString(DesCrypt.encrypt(DesCrypt.getDesKey(key), objBytes)); - } - } - - protected static final StorageHandler OLD_FUNNY_HASH_STORAGE_HANDLER = new LegacyStorageHandler() { - @Override - protected String getHashedKeyName(String originalKeyName) { - return HashCrypt.digestHashOldFunnyHex(null, originalKeyName); - } - - @Override - protected String getKeyMapPrefix(String hashedKeyName) { - return "{funny-hash}"; - } - }; - - protected static final StorageHandler NORMAL_HASH_STORAGE_HANDLER = new LegacyStorageHandler() { - @Override - protected String getHashedKeyName(String originalKeyName) { - return HashCrypt.digestHash("SHA", originalKeyName.getBytes()); - } - - @Override - protected String getKeyMapPrefix(String hashedKeyName) { - return "{normal-hash}"; - } - }; - - protected static final class SaltedBase64StorageHandler extends StorageHandler { - private final Key kek; - - protected SaltedBase64StorageHandler(byte[] kek) throws EntityCryptoException { - Key key = null; - if (kek != null) { - try { - key = DesCrypt.getDesKey(kek); - } catch (GeneralException e) { - Debug.logInfo("Invalid key-encryption-key specified for SaltedBase64StorageHandler; the key is probably " - + "valid for the newer ShiroStorageHandler", MODULE); - } - } - this.kek = key; - } - - @Override - protected Key generateNewKey() throws EntityCryptoException { - try { - return DesCrypt.generateKey(); - } catch (NoSuchAlgorithmException e) { - throw new EntityCryptoException(e); - } - } - - @Override - protected String getHashedKeyName(String originalKeyName) { - return HashCrypt.digestHash64("SHA", originalKeyName.getBytes(StandardCharsets.UTF_8)); - } - - @Override - protected String getKeyMapPrefix(String hashedKeyName) { - return "{salted-base64}"; - } - - @Override - protected byte[] decodeKeyBytes(String keyText) throws GeneralException { - byte[] keyBytes = Base64.decodeBase64(keyText); - if (kek != null) { - keyBytes = DesCrypt.decrypt(kek, keyBytes); - } - return keyBytes; - } - - @Override - protected String encodeKey(byte[] key) throws GeneralException { - if (kek != null) { - key = DesCrypt.encrypt(kek, key); - } - return Base64.encodeBase64String(key); - } - - @Override - protected byte[] decryptValue(byte[] key, EncryptMethod encryptMethod, String encryptedString) throws GeneralException { - byte[] allBytes = DesCrypt.decrypt(DesCrypt.getDesKey(key), Base64.decodeBase64(encryptedString)); - int length = allBytes[0]; - byte[] objBytes = new byte[allBytes.length - 1 - length]; - System.arraycopy(allBytes, 1 + length, objBytes, 0, objBytes.length); - return objBytes; - } - - @Override - protected String encryptValue(EncryptMethod encryptMethod, byte[] key, byte[] objBytes) throws GeneralException { - // This legacy handler is never used for new encryption -- EntityCrypto.encrypt() always - // encrypts through the primary ShiroStorageHandler; this method exists only so the class - // implements StorageHandler for its decrypt fallback role. - byte[] saltBytes = new byte[0]; - byte[] allBytes = new byte[1 + saltBytes.length + objBytes.length]; - allBytes[0] = (byte) saltBytes.length; - System.arraycopy(saltBytes, 0, allBytes, 1, saltBytes.length); - System.arraycopy(objBytes, 0, allBytes, 1 + saltBytes.length, objBytes.length); - String result = Base64.encodeBase64String(DesCrypt.encrypt(DesCrypt.getDesKey(key), allBytes)); - return result; - } - } } diff --git a/framework/entityext/src/main/java/org/apache/ofbiz/entityext/data/EntityDataServices.java b/framework/entityext/src/main/java/org/apache/ofbiz/entityext/data/EntityDataServices.java index a38f3c77cf..0776d7a61d 100644 --- a/framework/entityext/src/main/java/org/apache/ofbiz/entityext/data/EntityDataServices.java +++ b/framework/entityext/src/main/java/org/apache/ofbiz/entityext/data/EntityDataServices.java @@ -36,7 +36,6 @@ import java.util.Map; import java.util.Set; import org.apache.commons.codec.binary.Base64; -import org.apache.ofbiz.base.crypto.DesCrypt; import org.apache.ofbiz.base.util.Debug; import org.apache.ofbiz.base.util.FileUtil; import org.apache.ofbiz.base.util.GeneralException; @@ -478,13 +477,8 @@ public class EntityDataServices { try { keyBytes = cipherService.decrypt(keyBytes, Base64.decodeBase64(oldKey)).getClonedBytes(); } catch (Exception e) { - Debug.logInfo("Failed to decrypt with Shiro cipher; trying with old cipher", MODULE); - try { - keyBytes = DesCrypt.decrypt(DesCrypt.getDesKey(Base64.decodeBase64(oldKey)), keyBytes); - } catch (Exception e1) { - Debug.logError(e1, MODULE); - return ServiceUtil.returnError(e1.getMessage()); - } + Debug.logInfo("Failed to decrypt with Shiro cipher", MODULE); + return ServiceUtil.returnError(e.getMessage()); } } String newKeyText;

