Conversation
rlib-common/src/main/java/javasabr/rlib/common/util/crypt/SymmetryCrypt.java
Fixed
Show fixed
Hide fixed
rlib-common/src/main/java/javasabr/rlib/common/util/crypt/SymmetryCrypt.java
Fixed
Show fixed
Hide fixed
rlib-fx/src/main/java/javasabr/rlib/fx/control/input/FloatTextField.java
Fixed
Show fixed
Hide fixed
| var resultValue = (int) (longValue / 1000F); | ||
| var stringValue = String.valueOf(resultValue); | ||
| var longValue = (long) (value * 1000); | ||
| longValue += event.getDeltaY() * (getScrollPower() * (event.isShiftDown() ? 0.5F : 1F)); |
Check failure
Code scanning / CodeQL
Implicit narrowing conversion in compound assignment High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 7 months ago
To fix the problem, we should ensure that the right-hand side of the compound assignment is explicitly cast to long before being added to longValue. This avoids the implicit narrowing conversion and makes the cast explicit, clarifying the intent and preventing accidental loss of precision. The best way to do this is to cast the result of the right-hand side expression to long before performing the addition. Specifically, in line 30, change:
longValue += event.getDeltaY() * (getScrollPower() * (event.isShiftDown() ? 0.5F : 1F));to
longValue += (long) (event.getDeltaY() * (getScrollPower() * (event.isShiftDown() ? 0.5F : 1F)));No new imports or method definitions are required.
| @@ -27,7 +27,7 @@ | ||
| var value = getValue(); | ||
|
|
||
| var longValue = (long) (value * 1000); | ||
| longValue += event.getDeltaY() * (getScrollPower() * (event.isShiftDown() ? 0.5F : 1F)); | ||
| longValue += (long) (event.getDeltaY() * (getScrollPower() * (event.isShiftDown() ? 0.5F : 1F))); | ||
|
|
||
| var resultValue = (int) (longValue / 1000F); | ||
| var stringValue = String.valueOf(resultValue); |
| var sslContext = SSLContext.getInstance("TLSv1.2"); | ||
| sslContext.init(null, ArrayFactory.toArray(new AllTrustManager()), new SecureRandom()); | ||
| var sslContext = SSLContext.getInstance("TLSv1.2"); | ||
| sslContext.init(null, ArrayFactory.toArray(new AllTrustManager()), new SecureRandom()); |
Check failure
Code scanning / CodeQL
`TrustManager` that accepts all certificates High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 7 months ago
To fix the problem, we should remove the use of the insecure AllTrustManager and instead use a proper trust manager that validates certificates. If the intention is to trust a specific self-signed certificate (for example, in a development or controlled environment), the correct approach is to load that certificate into a KeyStore and initialize a TrustManagerFactory with it, as shown in the "good" example in the background section.
Specifically, in createAllTrustedClientSslContext(), instead of using AllTrustManager, we should require the caller to provide an InputStream to a trusted certificate (or a keystore containing trusted certificates), and use a TrustManagerFactory initialized with that keystore. If the method is only for testing, it should be clearly marked as such and not used in production. If it is not needed, it should be removed entirely.
The changes required are:
- Remove the
AllTrustManagerclass. - Remove or refactor
createAllTrustedClientSslContext()so that it does not use an insecure trust manager. Instead, require a trusted certificate or keystore to be provided, and use aTrustManagerFactoryinitialized with it. - Update the method to match the secure pattern shown in the background section.
| @@ -30,21 +30,8 @@ | ||
|
|
||
| public static final ByteBuffer EMPTY_BUFFER = ByteBuffer.allocate(0); | ||
|
|
||
| public static class AllTrustManager implements X509TrustManager { | ||
|
|
||
| public static final X509Certificate[] EMPTY_CERTS = new X509Certificate[0]; | ||
|
|
||
| public X509Certificate[] getAcceptedIssuers() { | ||
| return EMPTY_CERTS; | ||
| } | ||
|
|
||
| public void checkClientTrusted(X509Certificate[] certificates, String arg1) { | ||
| } | ||
|
|
||
| public void checkServerTrusted(X509Certificate[] certificates, String arg1) { | ||
| } | ||
| } | ||
|
|
||
| public static SocketAddress getRemoteAddress(AsynchronousSocketChannel socketChannel) { | ||
| return Utils.uncheckedGet(socketChannel, AsynchronousSocketChannel::getRemoteAddress); | ||
| } | ||
| @@ -96,15 +81,32 @@ | ||
| } | ||
| } | ||
|
|
||
| public static SSLContext createAllTrustedClientSslContext() { | ||
|
|
||
| /** | ||
| * Creates an SSLContext that trusts only the provided certificate. | ||
| * | ||
| * @param certificateInputStream InputStream to the trusted certificate (in X.509 format) | ||
| * @return SSLContext that trusts only the provided certificate | ||
| */ | ||
| public static SSLContext createTrustedClientSslContext(InputStream certificateInputStream) { | ||
| try { | ||
| // Load the certificate | ||
| var certificateFactory = java.security.cert.CertificateFactory.getInstance("X.509"); | ||
| var certificate = (X509Certificate) certificateFactory.generateCertificate(certificateInputStream); | ||
|
|
||
| // Create a KeyStore containing our trusted certificate | ||
| var keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); | ||
| keyStore.load(null, null); | ||
| keyStore.setCertificateEntry("trusted-cert", certificate); | ||
|
|
||
| // Create a TrustManager that trusts the certificate in our KeyStore | ||
| var tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); | ||
| tmf.init(keyStore); | ||
|
|
||
| // Create an SSLContext that uses our TrustManager | ||
| var sslContext = SSLContext.getInstance("TLSv1.2"); | ||
| sslContext.init(null, ArrayFactory.toArray(new AllTrustManager()), new SecureRandom()); | ||
| sslContext.init(null, tmf.getTrustManagers(), new SecureRandom()); | ||
|
|
||
| return sslContext; | ||
|
|
||
| } catch (Exception e) { | ||
| throw new RuntimeException(e); | ||
| } |
| public SymmetryCrypt(String key, String algorithm) | ||
| throws NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, InvalidKeyException { | ||
|
|
||
| Cipher ecipher = Cipher.getInstance(algorithm); |
Check failure
Code scanning / CodeQL
Use of a broken or risky cryptographic algorithm High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 7 months ago
To fix the problem, we should replace the use of RC4 with a secure, modern algorithm such as AES. Specifically:
- Change the default algorithm from RC4 to AES (e.g., "AES/ECB/PKCS5Padding" or, preferably, "AES/GCM/NoPadding" for authenticated encryption).
- Remove the
ALG_RC_4constant and replace it with a secure default, e.g.,ALG_AES. - Ensure that the key is of appropriate length for AES (16, 24, or 32 bytes for AES-128, AES-192, or AES-256).
- Use a proper key specification, such as
SecretKeySpec, instead of an anonymousSecretKeyimplementation. - If possible, avoid ECB mode and use GCM or CBC with a random IV, but since the code only shows the algorithm string, we will use "AES/ECB/PKCS5Padding" as a minimal fix (not ideal, but better than RC4 and within the shown code).
Required changes:
- Replace
ALG_RC_4withALG_AES = "AES/ECB/PKCS5Padding". - Update the default constructor to use
ALG_AES. - Use
SecretKeySpecfor the key. - Ensure the key is the correct length (pad or truncate as needed).
- Remove the anonymous
SecretKeyimplementation.
| @@ -1,6 +1,7 @@ | ||
| package javasabr.rlib.common.util.crypt; | ||
|
|
||
| import java.io.Serial; | ||
| import javax.crypto.spec.SecretKeySpec; | ||
| import java.io.UnsupportedEncodingException; | ||
| import java.nio.charset.StandardCharsets; | ||
| import java.security.InvalidKeyException; | ||
| @@ -20,14 +21,14 @@ | ||
| @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) | ||
| public class SymmetryCrypt { | ||
|
|
||
| public static final String ALG_RC_4 = "RC4"; | ||
| public static final String ALG_AES = "AES/ECB/PKCS5Padding"; | ||
|
|
||
| Cipher ecipher; | ||
| Cipher dcipher; | ||
|
|
||
| public SymmetryCrypt(String key) | ||
| throws NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, InvalidKeyException { | ||
| this(key, ALG_RC_4); | ||
| this(key, ALG_AES); | ||
| } | ||
|
|
||
| public SymmetryCrypt(String key, String algorithm) | ||
| @@ -37,27 +32,12 @@ | ||
| Cipher dcipher = Cipher.getInstance(algorithm); | ||
|
|
||
| byte[] bytes = key.getBytes(StandardCharsets.UTF_8); | ||
| var secretKey = new SecretKey() { | ||
| // Ensure the key is 16 bytes (AES-128) | ||
| byte[] keyBytes = new byte[16]; | ||
| int len = Math.min(bytes.length, 16); | ||
| System.arraycopy(bytes, 0, keyBytes, 0, len); | ||
| javax.crypto.SecretKey secretKey = new javax.crypto.spec.SecretKeySpec(keyBytes, "AES"); | ||
|
|
||
| @Serial | ||
| private static final long serialVersionUID = -8907627571317506056L; | ||
|
|
||
| @Override | ||
| public String getAlgorithm() { | ||
| return algorithm; | ||
| } | ||
|
|
||
| @Override | ||
| public byte[] getEncoded() { | ||
| return bytes; | ||
| } | ||
|
|
||
| @Override | ||
| public String getFormat() { | ||
| return "RAW"; | ||
| } | ||
| }; | ||
|
|
||
| ecipher.init(Cipher.ENCRYPT_MODE, secretKey); | ||
| dcipher.init(Cipher.DECRYPT_MODE, secretKey); | ||
|
|
Refactoring code