Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2.7] JCEEncryptor default encryption algorithm upgrade #2016

Merged
merged 1 commit into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions antbuild.properties
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ setenv-scripts=setenv.*
package-rename-scripts=packageRename.*
jaxb-compiler-scripts=jaxb-compiler.*
sdo-compiler-scripts=sdo-*.*
security-scripts=passwordUpdate.*

#Manifest Information
eclipselink.specification.title=Eclipse Persistence Services
Expand Down
4 changes: 4 additions & 0 deletions antbuild.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1699,6 +1699,10 @@
<zipfileset dir="${eclipselink.util.rename}" prefix="eclipselink/utils/rename" filemode="755">
<include name="${package-rename-scripts}"/>
</zipfileset>
<!-- password updater scripts -->
<zipfileset dir="${eclipselink.core.bin}" prefix="eclipselink/utils/security" filemode="755">
<include name="${security-scripts}"/>
</zipfileset>

<!-- jaxb-compiler scripts -->
<zipfileset dir="${eclipselink.moxy.bin}" includes="${jaxb-compiler-scripts}" prefix="eclipselink/bin" filemode="755"/>
Expand Down
1 change: 1 addition & 0 deletions etc/jenkins/pr_verify.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ spec:
steps {
container('el-build') {
sh """
export bind_address=0.0.0.0
/opt/bin/mysql-start.sh
mkdir $HOME/extension.lib.external
wget -nc https://repo1.maven.org/maven2/junit/junit/4.12/junit-4.12.jar -O $HOME/extension.lib.external/junit-4.12.jar
Expand Down
1 change: 1 addition & 0 deletions features/bundles/eclipselink/src/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
exports org.eclipse.persistence.platform.server.wls;
exports org.eclipse.persistence.platform.xml;
exports org.eclipse.persistence.queries;
exports org.eclipse.persistence.security;
exports org.eclipse.persistence.sequencing;
exports org.eclipse.persistence.services;
exports org.eclipse.persistence.services.glassfish;
Expand Down
47 changes: 47 additions & 0 deletions foundation/bin/passwordUpdate.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
@REM
@REM Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
@REM
@REM This program and the accompanying materials are made available under the
@REM terms of the Eclipse Public License v. 2.0 which is available at
@REM http://www.eclipse.org/legal/epl-2.0,
@REM or the Eclipse Distribution License v. 1.0 which is available at
@REM http://www.eclipse.org/org/documents/edl-v10.php.
@REM
@REM SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
@REM

@REM Usage is `passwordUpdate.sh|.cmd -ip <old encrypted password>`
@REM This application internally decrypt old encrypted password used by some previous version EclipseLink and encrypt it by latest algorithm.

@echo off
setlocal
call "%~dp0../../bin/setenv.cmd"

@REM User may increase Java memory setting(s) if desired:
set JVM_ARGS=-Xmx256m

REM Please do not change any of the following lines:
set _FIXPATH=
call :fixpath "%~dp0"
set THIS=%_FIXPATH:~1%

set CLASSPATH=%CLASSPATH%;%THIS%..\..\jlib\eclipselink.jar

set PASSWORD_UPDATE_ARGS=%*

%JAVA_HOME%\bin\java.exe %JVM_ARGS% -cp %CLASSPATH% org.eclipse.persistence.tools.security.JCEEncryptorCmd %PASSWORD_UPDATE_ARGS%

endlocal
goto :EOF

:fixpath
if not %1.==. (
for /f "tokens=1* delims=;" %%a in (%1) do (
call :shortfilename "%%a" & call :fixpath "%%b"
)
)
goto :EOF

:shortfilename
for %%i in (%1) do set _FIXPATH=%_FIXPATH%;%%~fsi
goto :EOF
28 changes: 28 additions & 0 deletions foundation/bin/passwordUpdate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/sh
#
# Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0,
# or the Eclipse Distribution License v. 1.0 which is available at
# http://www.eclipse.org/org/documents/edl-v10.php.
#
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#

#Usage is `passwordUpdate.sh|.cmd -ip <old encrypted password>`
#This application internally decrypt old encrypted password used by some previous version EclipseLink and encrypt it by latest algorithm.

. `dirname $0`/../../bin/setenv.sh

# User may increase Java memory setting(s) if desired:
JVM_ARGS=-Xmx256m

# Please do not change any of the following lines:
CLASSPATH=`dirname $0`/../../jlib/eclipselink.jar:

PASSWORD_UPDATE_ARGS="$@"

${JAVA_HOME}/bin/java ${JVM_ARGS} -cp ${CLASSPATH} \
org.eclipse.persistence.tools.security.JCEEncryptorCmd ${PASSWORD_UPDATE_ARGS}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -21,12 +21,14 @@
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.security.JCEEncryptor;
import org.eclipse.persistence.internal.security.Securable;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.junit.Assert;
import org.junit.Test;

Expand All @@ -35,82 +37,114 @@
* @author dminsky
*/
public class SecurableBackwardsCompatibilityTest {

/**
* Test the decryption of a String encrypted with DES ECB.
* @throws Exception
*/
@Test
public void testStringDecryption_DES_ECB() throws Exception {
String plainTextString = "welcome123_des_ecb";

String testString = encryptString_DES_ECB(plainTextString);
Assert.assertFalse("Strings should not match.", plainTextString.equals(testString));

Securable securable = new JCEEncryptor();
String decryptedString = securable.decryptPassword(testString);
Assert.assertEquals("Strings should match.", plainTextString, decryptedString);
}


/**
* Test the decryption of a String encrypted with AES GCM.
*/
@Test
public void testStringDecryption_AES_GCM() throws Exception {
String plainTextString = "welcome123_aes_gcm";

Securable securable = new JCEEncryptor();
String testString = securable.encryptPassword(plainTextString);
Assert.assertFalse("Strings should not match.", plainTextString.equals(testString));

String decryptedString = securable.decryptPassword(testString);
Assert.assertEquals("Strings should match.", plainTextString, decryptedString);
}

/**
* Test the decryption of a String encrypted with AES CBC.
* @throws Exception
*/
@Test
public void testStringDecryption_AES_CBC() throws Exception {
String plainTextString = "welcome123_aes_cbc";

Securable securable = new JCEEncryptor();
String testString = securable.encryptPassword(plainTextString);
String testString = encryptString_AES_CBC(plainTextString);
Assert.assertFalse("Strings should not match.", plainTextString.equals(testString));


Securable securable = new JCEEncryptor();
String decryptedString = securable.decryptPassword(testString);
Assert.assertEquals("Strings should match.", plainTextString, decryptedString);
}

/**
* Test the decryption of a String encrypted with AES ECB.
* @throws Exception
*/
@Test
public void testStringDecryption_AES_ECB() throws Exception {
String plainTextString = "welcome123_aes_ecb";

String testString = encryptString_AES_ECB(plainTextString);
Assert.assertFalse("Strings should not match.", plainTextString.equals(testString));

Securable securable = new JCEEncryptor();
String decryptedString = securable.decryptPassword(testString);
Assert.assertEquals("Strings should match.", plainTextString, decryptedString);
}


@Test
public void testStringDecryption_AES_ECB_withSessionName() throws Exception {
String plainTextString = "welcome123_aes_ecb";

String testString = encryptString_AES_ECB(plainTextString);
Assert.assertFalse("Strings should not match.", plainTextString.equals(testString));

JCEEncryptor jceEncryptor = new JCEEncryptor();
jceEncryptor.setSessionName("/file:/testdir/_test-jpa-pu");
String decryptedString = jceEncryptor.decryptPassword(testString);
Assert.assertEquals("Strings should match.", plainTextString, decryptedString);
}

/**
* Test the decryption/processing of a plaintext String.
* @throws Exception
*/
@Test
public void testStringDecryption_PlainText() throws Exception {
String plainTextString = "welcome123_plaintext";

Securable securable = new JCEEncryptor();
String decryptedString = securable.decryptPassword(plainTextString);
Assert.assertEquals("Passwords should match.", plainTextString, decryptedString);
}


/**
* Test the decryption/processing of an empty String "".
*/
@Test
public void testEmptyStringParameterDecryption() throws Exception {
Securable securable = new JCEEncryptor();
String returnValue = securable.decryptPassword("");
Assert.assertEquals("Empty string \"\" should be returned when decrypting a \"\" (empty string) value", "", returnValue);
}

/**
* Test the decryption/processing of a null parameter.
* @throws Exception
*/
@Test
public void testNullParameterDecryption() throws Exception {
Securable securable = new JCEEncryptor();
String returnValue = securable.decryptPassword(null);
Assert.assertNull("Null should be returned when decrypting a null value", returnValue);
}

/**
* Test the encryption of a null parameter.
* @throws Exception
*/
@Test
public void testNullParameterEncryption() throws Exception {
Expand All @@ -123,17 +157,17 @@ public void testNullParameterEncryption() throws Exception {
}
Assert.assertNotNull("A ValidationException should be thrown when encrypting a null value", expectedException);
}

/*
* Internal test utility:
* Return a DES ECB encrypted version of the String parameter, using the legacy encryption code.
*/
private String encryptString_DES_ECB(String aString) throws Exception {
final byte[] bytes = Helper.buildBytesFromHexString("E60B80C7AEC78038");

Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, SecretKeyFactory.getInstance("DES").generateSecret(new DESKeySpec(bytes)));

ByteArrayOutputStream baos = new ByteArrayOutputStream();
CipherOutputStream cos = new CipherOutputStream(baos, cipher);
ObjectOutputStream oos = new ObjectOutputStream(cos);
Expand All @@ -143,17 +177,31 @@ private String encryptString_DES_ECB(String aString) throws Exception {

return Helper.buildHexStringFromBytes(baos.toByteArray());
}


/*
* Internal test utility:
* Return an AES CBC encrypted version of the String parameter, using the legacy encryption code.
*/
private String encryptString_AES_CBC(String aString) throws Exception {
final byte[] bytes = Helper.buildBytesFromHexString("2DB7354A48F1CA7B48ACA247540FC923");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = getIvSpec();
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(bytes, "AES"), iv);

return Helper.buildHexStringFromBytes(cipher.doFinal(aString.getBytes("UTF-8")));
}

/*
* Internal test utility:
* Return an AES ECB encrypted version of the String parameter, using the legacy encryption code.
*/
private String encryptString_AES_ECB(String aString) throws Exception {
final byte[] bytes = Helper.buildBytesFromHexString("3E7CFEF156E712906E1F603B59463C67");

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(bytes, "AES"));

ByteArrayOutputStream baos = new ByteArrayOutputStream();
CipherOutputStream cos = new CipherOutputStream(baos, cipher);
ObjectOutputStream oos = new ObjectOutputStream(cos);
Expand All @@ -163,5 +211,13 @@ private String encryptString_AES_ECB(String aString) throws Exception {

return Helper.buildHexStringFromBytes(baos.toByteArray());
}


private static IvParameterSpec getIvSpec() {
byte[] b = new byte[] {
(byte) -26, (byte) 124, (byte) -99, (byte) 32,
(byte) -37, (byte) -58, (byte) -93, (byte) 100,
(byte) 126, (byte) -55, (byte) -21, (byte) 48,
(byte) -86, (byte) 97, (byte) 12, (byte) 113};
return new IvParameterSpec(b);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,16 @@ public class LoggingLocalizationResource extends ListResourceBundle {
{ "validate_object_space", "validate object space." },
{ "stack_of_visited_objects_that_refer_to_the_corrupt_object", "stack of visited objects that refer to the corrupt object: {0}" },
{ "corrupt_object_referenced_through_mapping", "corrupt object referenced through mapping: {0}" },
{ "corrupt_object", "corrupt object: {0}" }
{ "corrupt_object", "corrupt object: {0}" },

{ "encryptor_decrypt_old_algorithm", "Database password used in {0} was encrypted by deprecated algorithm." +
"\nIt is recommended to re-encrypt it by `passwordUpdate.sh` from eclipselink.zip bundle."},
{ "encryptor_decrypt_old_algorithm_without_session_name", "Database password was encrypted by deprecated algorithm." +
"\nIt is recommended to re-encrypt it by `passwordUpdate.sh` from eclipselink.zip bundle."},
{ "encryptor_script_usage", "Usage is `passwordUpdate.sh|.cmd -ip <old encrypted password>`"},
{ "encryptor_script_description", "This application internally decrypt old encrypted password used by some previous version EclipseLink and encrypt it by latest algorithm."},
{ "encryptor_script_output", "Re-encrypted password is: {0}"}

};

/**
Expand Down
Loading
Loading