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

Fix #2075 Slow startup because of low entropy for PRNG #2318

Merged
merged 2 commits into from
Dec 16, 2024

Conversation

tnagao7
Copy link
Member

@tnagao7 tnagao7 commented Dec 3, 2024

Fixes #2075.

To address hang-up due to blocking PRNG returned by SecureRandom.getInstanceStrong(), this pull request introduces a system property (eclipselink.security.encryptor.use.strong.random.number.generator) to switch SecureRandom.getInstanceStrong() and new SecureRandom().
new SecureRandom() returns the default PRNG of Java platform [1].

Since SecureRandom.getInstanceStrong() may return a blocking PRNG and is not recommended in server-side code (see [2]), we prefer to use new SecureRandom() as the default setting.
Users can change the behavior by configuring the system property if they want.

[1] https://docs.oracle.com/en/java/javase/21/security/java-cryptography-architecture-jca-reference-guide.html#GUID-AEB77CD8-D28F-4BBE-B9E5-160B5DC35D36
[2] https://www.blackduck.com/blog/proper-use-of-javas-securerandom.html

@tnagao7
Copy link
Member Author

tnagao7 commented Dec 12, 2024

Can anyone review this patch?

Copy link

@dmatej dmatej left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have just one question - does it need to be new SecureRandom instance every time, with a new seed? Maybe yes as it is used to encrypt database passwords, but I could not resist to ask ;-)

@alwinmark
Copy link

Hello @rfelcman,

as you were the last one touching that file, could you please review this Pullrequest? It would be awesome if we could fix this soon as it affects our CI-Builds and also may affect Cloud Applications.

} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
String useStrongRNG = PrivilegedAccessHelper.getSystemProperty(SystemProperties.SECURITY_ENCRYPTOR_USE_STRONG_RANDOM_NUMBER_GENERATOR);
if (Boolean.parseBoolean(useStrongRNG)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will change default behavior into less secure mode by default.
But I'd like rephrase it and change condition content. If users needs it e.g. due performance reasons, they could enable it by system property like
SECURITY_ENCRYPTOR_USE_NON_BLOCKING_RANDOM_NUMBER_GENERATOR = "eclipselink.security.encryptor.non.blocking.random.number.generator"; -> random = new SecureRandom();
For me in this case security is higher, than performance so I'd like keep as a default random = SecureRandom.getInstanceStrong(); and conditionally random = new SecureRandom();

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand your concerns.
But IMHO, this pull request does not immediately lower the security level, because it does not change the cipher (AES GCM) for encryption, and using new SecureRandom() as random source is still secure.

From the viewpoint of availability, the impact of stall (almost hang in some environments) due to blocking algorithms cannot be ignored.
If a blocking algorithm is used by default, users might encounter the stall in a production environment, which can cause business losses.
There are several related discussions discouraging use of SecureRandom.getInstanceStrong() in server-side applications:

Should we still use SecureRandom.getInstanceStrong()?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I accepted Your arguments. I don't like blocked production systems too. Lets use new SecureRandom as a default.

} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
String useStrongRNG = PrivilegedAccessHelper.getSystemProperty(SystemProperties.SECURITY_ENCRYPTOR_USE_STRONG_RANDOM_NUMBER_GENERATOR);
if (Boolean.parseBoolean(useStrongRNG)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like see there validation for input see e.g.
https://github.com/eclipse-ee4j/eclipselink/blob/master/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/asm/ASMFactory.java#L268
and throw throw ValidationException.incorrect..... to point user what is wrong.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your advice.
I tried to find examples of boolean value validation to meet your expectation, but I could not find a good example...

For example, java.lang.Boolean.parseBoolean() can be used to parse boolean values, but the method cannot be used for validation since it does not throw exceptions.
Validation could be achieved as in if (!"true".equalsIgnoreCase(value) && !"false".equalsIgnoreCase(value)) { throw ... }, but such code is not pretty.
Could you suggest a good way to validate boolean values if you have?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I don't have anything better. Similar pattern "true".equals.... is used sometimes inside EclipseLink e.g.
https://github.com/eclipse-ee4j/eclipselink/blob/master/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/EntityManagerImpl.java#L275
Just use this "not pretty" pattern and throw org.eclipse.persistence.exceptions.ValidationException#invalidBooleanValueForProperty.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have reflected your comment now. Please check it.
If an invalid value is specified, an exception like below is thrown.

Exception [EclipseLink-7278] (Eclipse Persistence Services - 5.0.0.v202412160411-a5af5837377bcad2adc674a0682717d24a436f69): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The specified boolean value [aaa] for the persistence property [eclipselink.security.encryptor.use.strong.random.number.generator] is invalid, the value must either be "true" or "false".

@tnagao7
Copy link
Member Author

tnagao7 commented Dec 13, 2024

I have just one question - does it need to be new SecureRandom instance every time, with a new seed? Maybe yes as it is used to encrypt database passwords, but I could not resist to ask ;-)

I'm not sure the reason why the original implementation is creating new SecureRandom instance (i.e. calling SecureRandom.getInstanceStrong()) every time...

In my recognition, there is at least no security problem with creating new SecureRandom instance every time because of non-deterministic nature of SecureRandom.
If there are other concerns such as performance issues, we can address it with another pull request.

Copy link
Contributor

@rfelcman rfelcman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LTGM

@rfelcman rfelcman merged commit 4ef3517 into eclipse-ee4j:master Dec 16, 2024
6 checks passed
@rfelcman
Copy link
Contributor

It's going to master branch (5.0.x ) EclipseLink version. If You need it in older versions please make a backports.

Zuplyx added a commit to Zuplyx/eclipselink that referenced this pull request Dec 20, 2024
…clipse-ee4j#2318)

* Fix hang-up due to blocking PRNG returned by SecureRandom.getInstanceStrong()
Fixes eclipse-ee4j#2075

(cherry picked from commit 4ef3517)
Signed-off-by: Patrick Schmitt <[email protected]>
Zuplyx added a commit to Zuplyx/eclipselink that referenced this pull request Dec 21, 2024
…clipse-ee4j#2318)

* Fix hang-up due to blocking PRNG returned by SecureRandom.getInstanceStrong()
Fixes eclipse-ee4j#2075

(cherry picked from commit 4ef3517)
Signed-off-by: Zuplyx <[email protected]>
rfelcman pushed a commit that referenced this pull request Dec 22, 2024
* Fix hang-up due to blocking PRNG returned by SecureRandom.getInstanceStrong()
Fixes #2075

(cherry picked from commit 4ef3517)
Signed-off-by: Zuplyx <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Slow startup because of low entropy for PRNG
4 participants