With the entered code here, I am trying to build a project on springboot. I am using AES encryption in my project. I am keeping the password(key) of AES in the application properties. The variable and method in the AES class are static. I use static for using the method without creating an instance of the class. But I can't inject the value into the static variable in the AES class. I injected using a workaround method, which is injecting the value to the instance variable and then passing it to the static variable. I also wrote setter method to inject, but these methods throwing warning in the SonarQube. I am using SonarQube to validate my code. I don't know what to do. I just supressed the warning. Is there any way to inject value without triggering the warning in SonarQube.
package com.example.demo.utils;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.crypto.*;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;
@Component
public class AESUtils {
@Getter
private static String password;
@SuppressWarnings("squid:S2696")
@Value("${aes.secret.key}")
public void setPassword(String injectedPassword) { // Spring calls this
AESUtils.password = injectedPassword;
}
// AES parameters
private static final int GCM_IV_LENGTH = 12; // 12-byte IV recommended
private static final int GCM_TAG_LENGTH = 128; // 128-bit authentication tag
private static final int PBKDF2_ITERATIONS = 51159; // For key derivation
private static final int PBKDF2_KEY_LENGTH = 256;
private static final SecureRandom secureRandom = new SecureRandom();
// ================================================
// Encrypt a plaintext string using AES-GCM
// Generates a random IV for each encryption
// Returns Base64-encoded string: IV + ciphertext
// ================================================
public static String encrypt(String plainText) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeyException {
// Generate random 12-byte IV
byte[] iv = new byte[GCM_IV_LENGTH];
secureRandom.nextBytes(iv);
// Derive AES key from password
SecretKey key = deriveKey(password, iv); // using IV as salt
// Initialize cipher
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH, iv);
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
// Encrypt plaintext
byte[] cipherText = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
// Prepend IV to ciphertext
byte[] ivAndCipher = new byte[iv.length + cipherText.length];
System.arraycopy(iv, 0, ivAndCipher, 0, iv.length);
System.arraycopy(cipherText, 0, ivAndCipher, iv.length, cipherText.length);
// Base64 encode for easy storage/transmission
return Base64.getUrlEncoder().withoutPadding().encodeToString(ivAndCipher);
}
// ================================================
// Decrypt a Base64-encoded ciphertext string
// Extracts IV from first 12 bytes
// Returns original plaintext
// ================================================
public static String decrypt(String base64CipherText) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
byte[] ivAndCipher = Base64.getUrlDecoder().decode(base64CipherText);
// Extract IV
byte[] iv = new byte[GCM_IV_LENGTH];
System.arraycopy(ivAndCipher, 0, iv, 0, GCM_IV_LENGTH);
// Extract ciphertext
byte[] cipherText = new byte[ivAndCipher.length - GCM_IV_LENGTH];
System.arraycopy(ivAndCipher, GCM_IV_LENGTH, cipherText, 0, cipherText.length);
// Derive AES key from password
SecretKey key = deriveKey(password, iv); // same IV used as salt
// Initialize cipher
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH, iv);
cipher.init(Cipher.DECRYPT_MODE, key, spec);
// Decrypt
byte[] plainBytes = cipher.doFinal(cipherText);
return new String(plainBytes, StandardCharsets.UTF_8);
}
// ================================================
// Derive AES key from password using PBKDF2 with HMAC-SHA256
// Salt ensures unique key per encryption
// ================================================
private static SecretKey deriveKey(String password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, PBKDF2_ITERATIONS, PBKDF2_KEY_LENGTH);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
byte[] keyBytes = factory.generateSecret(spec).getEncoded();
return new SecretKeySpec(keyBytes, "AES");
}
}
AESUtils, is it your class? If yes, add its code pls to your question